2

Here's my issue. I am doing two things with arcpy:

1) I search a feature class using arcpy.da.SearchCursor() and pull out a UID field and the geometry in WKB format for all polygons in the file, storing them in a dictionary.

2) I open a different, but similar feature class and use arcpy.da.UpdateCursor() to update the geometries of polygons that have the same UID as above.

The problem is not all of the polygons are getting updated, even though the exact same UIDS exist in both feature classes. Some of them update just fine, but just under half do not.

import arcpy, time

updated_rid_dict = {}
updated_rows = 0

# Grab UIDs and geometries of updated regions
with arcpy.da.SearchCursor(good_geometry_shape, field_names=['RegionID', 'SHAPE@WKB']) as cursor:
    for row in cursor:
        updated_rid_dict[row[0]] = row[1]
print "{} updated regions found".format(len(updated_rid_dict)) # returns 594

# Open an edit session and attempt to find all the regions in updated_rid_dict
edit = arcpy.da.Editor([path to my data])
edit.startEditing(False, False)
edit.startOperation()

with arcpy.da.UpdateCursor(bad_geometry_shape, field_names=['RegionID', 'SHAPE@WKB']) as cursor:
    for row in cursor:
        # See if the feature is in the updated_rid_dict
        if row[0] in updated_rid_dict:
            updated_rows += 1
            del updated_rid_dict[row[0]]

edit.stopOperation()
edit.stopEditing(True)

print "{} rows updated.".format(updated_rows) # Returns only 313

The code above doesn't even attempt to do an update. I can literally change "UpdateCursor" to "SearchCursor" and suddenly arcpy can find all the polygons in updated_rid_dict. I change it back to "UpdateCursor" and arcpy can only find some of the regions. I'm clueless as to what could be going wrong. Any ideas?

UPDATE: Using normal cursors does not fix the problem. Further testing shows that arcpy.da.UpdateCursor() iterates through every record up to OID 16781, then stops. Does UpdateCursor have some sort of limitations I'm not aware of? 16,781 records doesn't seem like that many to me.

  • You talk about UID's but the field you pull out is RegionID. May be you have many rows belonging to the same region and this would be the discrepancy. Basically regionID is not a unique number. – Hornbydd Jun 15 '15 at 22:13
  • Another thing I would do is run your update cursor on both datasets, not updating just pulling out the ID values and compare just to see if it is doing some weirdness to the values? – Hornbydd Jun 15 '15 at 22:16
  • where is cursor.UpdateRow(row)? where are you copying/replacing the 'to' geometry, all I see is del updated_rid_dict[row[0]], shouldn't there be row[1] = something? Is your 'to' feature class slightly broken? is that why you're trying to fix it? Perhaps a repair geometry could help.. – Michael Stimson Jun 15 '15 at 22:36
  • Could you comment out the del updated_rid_dict[row[0]] part and report the count, please? If it turns to correct (i.e., 594), then @Hornbydd's first comment reflects your problem, RegionID may not be necessarily unique. Otherwise, you can test normal cursors (arcpy.SearchCursor, etc.) to see if the issue persists. – fatih_dur Jun 15 '15 at 23:19
  • I've confirmed that there are no duplicate ids in either feature class. RegionIDs are all unique. When I use A arcpy.da.SearchCursor(), it finds everything. When I change only that call and nothing else to arcpy.da.UpdateCursor(), it doesn't find everything. I will try normal cursors as fatih_dur suggests. Thanks everyone. – AJSmyth Jun 17 '15 at 17:19
0

Found the solution, though I have no idea why it works. The code works if I move edit.startOperation() and edit.stopOperation() inside the loop:

# Open an edit session and attempt to find all the regions in updated_rid_dict
edit = arcpy.da.Editor([path to my data])
edit.startEditing(False, False)

with arcpy.da.UpdateCursor(bad_geometry_shape, field_names=['RegionID', 'SHAPE@WKB']) as cursor:
    for row in cursor:
        # See if the feature is in the updated_rid_dict
        if row[0] in updated_rid_dict:
            edit.startOperation()
            updated_rows += 1
            edit.stopOperation()

edit.stopEditing(True)

It's not clear at all to me why arcpy needs this, especially since this code doesn't actually execute any edits. If anyone has a thought, please comment below! Thanks for all your suggestions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.