1

My script supposed to go through all rows in one dataset, fl1:

  • select one row at a time,
  • based on that selection, select spatially from another dataset, fl2
  • if spatially identical records were found, update some columns from fl1 to fl2.

My script only does through one record. What am I missing to get going through every row in fl1? I thought that SearchCursor goes from one row to the next.

with arcpy.da.SearchCursor(fc1, fields1) as search_cur:
    for search_row in search_cur:
        with arcpy.da.UpdateCursor(fc2, fields2) as upd_cur:
            for upd_row in upd_cur:
                # select this record in fc1
                whereClause = "ObjectID_1 = {0}".format(search_row[0])
                #fl1 = rcpy.MakeFeatureLayer_management(fl1, 'fl1') # creating feature layer
                arcpy.SelectLayerByAttribute_management(fl1, "NEW_SELECTION", whereClause)
                # check for spatial intersect
                #fl2 = arcpy.MakeFeatureLayer_management(fl2, 'fl2') # creating feature layer
                arcpy.SelectLayerByLocation_management(fl2, "ARE_IDENTICAL_TO", fl1, "", "NEW_SELECTION")
                # check for selection in fl2
                desc=arcpy.Describe("fl2")
                if not desc.FIDSet:                            
                    # if selection is not empty
                    print search_row[1]
  • Do you get any error messages? What is if not desc.FIDSet: trying to do? I notice you are using a mix of fl2 (variable) and "fl2" (literal) this might cause problems depending on the value of the fl2 variable. – Michael Stimson Dec 5 '18 at 1:17
  • 2
    Rather than run an update cursor within a search cursor, I think you will get much better performance by using your search cursor to create a dictionary, and then using your update cursor separately to retrieve values from the dictionary. – PolyGeo Dec 5 '18 at 1:22
  • desc.FIDSet is checking if I have any features selected. If there is no selection, there is nothing to update. – lida Dec 5 '18 at 2:03
  • To answer your original question, I think the reason it only runs once is that cursors will limit themselves to selected records. In the first row of the searchcursor, you select that same row. Since that is now the only record to loop over, the search cursor thinks it is finished. – Marc Pfister Dec 5 '18 at 3:43
4

You don't need to use selections in your search cursor, you can grab the geometry of each feature in FC1:

with arcpy.da.SearchCursor(fc1, ["SHAPE@", "MY_DEBUG_FIELD", "SOME_OTHER_FIELD") as search_cur:
    for search_row in search_cur:
        # SHAPE@ is a magic token that gets the geometry of the feature
        geom = search_row[0]
        arcpy.SelectLayerByLocation_management(fl2, "ARE_IDENTICAL_TO", geom, "", "NEW_SELECTION")
        # do what you need to do with the selected feature
        # as suggested above, you could populate a dictionary with changes
        # and then use an UpdateCursor to apply those changes
  • that works, except that the loop never ends. what is the best way to stop it going once done? – lida Dec 5 '18 at 2:50
  • 1
    The loop should end when it is finished with all the rows. You may want to add a print statement to track what it's working on - perhaps a count of rows that have been searched. Then you can see if it's running, or if it's somehow stuck. – Marc Pfister Dec 5 '18 at 3:28

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.