Select to view content in your preferred language

Cursor Searching 2 tables and Updating a 3rd

5654
4
06-14-2012 02:45 PM
MikeMacRae
Frequent Contributor
Hey everyone,

I am trying to:


  1. Set a search cursor through table 1 which contains 2 fields. S_RANK and DESCRIPTION

  2. within the first loop, I am cursor searching through Table 2 which contains 2 fields. G_RANK and DESCRIPTION

  3. Updating a cursor on table 3 which contains 2 fields. ANHIC_RANK and DESCRIPTION


In the update cursor, I want to populate ANHIC_RANKING field in table 3 with a concatenation of S_RANK + G_RANK from the first. I want to update the DESCRIPTION field in table 3 with a concatenation of the 2 DESCRIPTION fields from the first 2 tables (i.e. DESCRIPTION + " + " + DESCRIPTION)

The print statements in the first 2 loops print out fine, it's the update cursor that doesn't seem to update. Any suggestions?

Thanks,
Mike

import arcpy
from arcpy import env

env.workspace = r"Z:\IOR\2012\2012_Geodatabase_UTM\DOMAIN_CODE_TABLES.gdb"

for x in arcpy.SearchCursor("ANHIC_RANK_S"):
    print x.S_RANK
    print x.DESCRIPTION

    for y in arcpy.SearchCursor("ANHIC_RANK_G"):
        print y.G_RANK
        print y.DESCRIPTION

        with arcpy.da.UpdateCursor("ANHIC_RANKING_FINAL", ["ANHIC_RANKING", "DESCRIPTION"]) as cursor:

            for row in cursor:
                row.ANHIC_RANKING = x.S_RANK + y.G_RANK
                row.DESCRIPTION = x.DESCRIPTION + " + " + y.DESCRIPTION
                c.updateRow(row)

Tags (2)
0 Kudos
4 Replies
NobbirAhmed
Esri Regular Contributor
You are using da UpdateCursor for the 3rd table. So, modify the assignment code by row[index] = value:

for row in cursor:
    row[0] = x.S_RANK + y.G_RANK
    row[1] = x.DESCRIPTION + " + " + y.DESCRIPTION 
    cursor.updateRow(row)
0 Kudos
markdenil
Frequent Contributor
You are also nesting the cursors, so for every record in the first table you run a cursor through the whole of table two,
and for every record in table two, each time it is run, you run through and update every record in the third table.

This seems a very odd thing to do.

It was easier to run multiple parallel cursors in Arc9, where one explicitly stepped each cursor forward (as one still does with an Insert Cursor).
In 10, where one itterates the cursor instead of stepping it (simpler, but in this case, less flexiable), things are trickier.

I suggest running the search cursors independantly first. Store the extracted values in a list or dictionary (as appropriate).
Then run the Update Cursor.
If using lists of output from the searches, also increment a counter and access the values from the list using the counter as a list index.
If using a dictionary, access by key.
0 Kudos
NobbirAhmed
Esri Regular Contributor
Make two lists from the first two tables with SearchCursor.

Use Python's zip function to combine two lists - item by item.

Finally, iterate over the UpdateCursor and update using the values from the zipped list.

Here is my sample code for your case:

import arcpy

# setting workspace and then using the data name is better
s_rank_fc = r"path_to_your_data\s_rank.shp"
g_rank_fc = r"path_to_your_data\g_rank.shp"
anhic_fc = r"path_to_your_data\anhic.shp"

rows_s = arcpy.SearchCursor(s_rank_fc)
# use list comprehension to create a list of lists
# each item is a list of two values rank and description
s_rank_list = [[row_s.CLASS, row_s.CLASS_DESC] for row_s in rows_s]

rows_g = arcpy.SearchCursor(g_rank_fc)
# use list comprehension to create a list of lists
# each item is a list of two values rank and description
g_rank_list = [[row_g.CLASS, row_g.CLASS_DESC] for row_g in rows_g]

# zip two lists
s_g_list = zip(s_rank_list, g_rank_list)

# open an UpdateCursor
rows = arcpy.UpdateCursor(anhic_fc)

i = 0  # this index is used to extract values from the zipped list

for row in rows:

    s_rank_desc = s_g_list[0]
    s_rank = s_rank_desc[0]
    s_desc = s_rank_desc[1]
    
    g_rank_desc = s_g_list[1]
    g_rank = g_rank_desc[0]
    g_desc = g_rank_desc[1]
    
    row.CLASS = s_rank + g_rank
    row.CLASS_DESC = s_desc + "; " + g_desc
    rows.updateRow(row)
    
    i += 1
    
del row
del rows
0 Kudos
MikeMacRae
Frequent Contributor
Thanks people,

With your suggestions and modifications, I was able to crack the code I needed. I ended up creating 2 lists and updated the final table that way. I believe the reason why my table wouldn't update is because I created it from scratch and it didn't have any rows. I had to insert the rows first and then update them. I have a feeling if I tested the insert cursor and used that to update as I add rows, instead of using a second step with the update cursor, that would probably work too. I'll post for anyone interested.

Oh and thanks to Nobbir for introducing me to the 'zip' function. It was very useful!

import arcpy
from arcpy import env

env.workspace = r"Z:\IOR\2012\2012_Geodatabase_UTM\DOMAIN_CODE_TABLES.gdb"

rankList = []
descList = []
z = 1

# set a search cursor to create every combination of x + y for both the RANK fields and the DESCRIPTION fields and build a list for each
for x in arcpy.SearchCursor("ANHIC_RANK_S"):

    for y in arcpy.SearchCursor("ANHIC_RANK_G"):
        rankList.append(x.S_RANK + y.G_RANK)
        descList.append(x.DESCRIPTION + " + " + y.DESCRIPTION)

# Open an insert cursor to insert the correct number of rows in the new table
insertCursor = arcpy.InsertCursor("ANHIC_RANKING_FINAL")
z = 1

while z <= len(rankList):
    row = insertCursor.newRow()
    rows.insertRow(row)
    z +=1


# zip each list
rank = zip(rankDict)
desc = zip(descDict)

# open an UpdateCursor on the final table
rows = arcpy.UpdateCursor("ANHIC_RANKING_FINAL")

i = 0  # this index is used to extract values from the zipped list

for row in rows:
    
    row.ANHIC_RANKING = rank[0]
    row.DESCRIPTION = desc[0]
    rows.updateRow(row)
    
    i += 1
    
del row
del rows
0 Kudos