Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm trying unsuccessfully to perform updates on multiple linked tables using updatecursors.

The following code works as I would expect:

trackRows = arcpy.SearchCursor("tracks","Key_='b2879561-d751-e111-9e92-0050568e18a0'")
for trackRow in trackRows:
    arcpy.management.MakeFeatureLayer("tracks","currentTrack","Key_='" + str(trackRow.Key_) + "'")
    grXingRows = arcpy.SearchCursor(GradeCrossings,"LinkKey='" + str(trackRow.Key_) + "'");
    for grxrow in grXingRows:
        inspectionRows = arcpy.SearchCursor(Inspections,"LinkKey='" + str(grxrow.getValue("Key_")) + "'")
        for insprow in inspectionRows:
            grxDefRows = arcpy.UpdateCursor(GradeCrossingDefects,"LinkKey='" + str(insprow.getValue("Key")) + "'")
            for grxdefrow in grxDefRows:
                grxdefrow.LocationVal = 7
                grxDefRows.updateRow(grxdefrow)
            del(grxDefRows)
        del(insprow)
    del(grXingRows)
    arcpy.management.Delete("currentTrack")

However, when I change the 4th line to use arcpy.UpdateCursor, the script still runs, but the data rows that are updated in the inner loop don't get updated in the DB.

Any ideas?

EDIT: Having tested out the suggestions about deleting cursors and rows more thoroughly, I now have the following:

trackRows = arcpy.SearchCursor("tracks","Key_='b2879561-d751-e111-9e92-0050568e18a0'")
for trackRow in trackRows:
    arcpy.management.MakeFeatureLayer("tracks","currentTrack","Key_='" + str(trackRow.Key_) + "'")
    grXingRows = arcpy.UpdateCursor(GradeCrossings,"LinkKey='" + str(trackRow.Key_) + "'");
    for grxrow in grXingRows:
        inspectionRows = arcpy.SearchCursor(Inspections,"LinkKey='" + str(grxrow.getValue("Key_")) + "'")
        for insprow in inspectionRows:
            grxDefRows = arcpy.UpdateCursor(GradeCrossingDefects,"LinkKey='" + str(insprow.getValue("Key")) + "'")
            for grxdefrow in grxDefRows:
                grxdefrow.LocationVal = 7
                grxDefRows.updateRow(grxdefrow)
                del(grxdefrow)
            del(grxDefRows)            
            del(insprow)
        del(inspectionRows)
        del(grxrow)
    del(grXingRows)
    arcpy.management.Delete("currentTrack")
    del(trackRow)
del(trackRows)

Still no luck! I tried deleting the rows within the loop, and tried deleting the rows outside of the loop. Neither solved my problem.

EDIT: Now I feel a little silly. I had a map service running which was maintaining a lock on BOTH of the feature classes I was trying to update. I used arcpy.TestSchemaLock to test, and found that it returned false for both feature classes regardless of whether the first was using a searchcursor or an updatecursor. Stopping the service solved my issue. However there is still some funny behavior here that I'd like to understand:

  1. According to the documentation, if the updatecursor can't get an exclusive lock, then it should error out...but my script ran just fine, no errors...why?
  2. Even given that not erroring were a valid behavior, I still should not have been successful with the inner update EVER when the service was running, but it worked fine as long as it was the only updatecursor I was using. Why?

EDIT: After sleeping on it and trying again, it seems the success from 2 days ago was a fluke. Both yesterday and today I have been unable to get the script to update the database correctly. The script is unchanged, and I have checked to ensure that there are no schemalocks on these feature classes (TestSchemaLock returns true). I'm not sure what stars had aligned which are now misaligned, but I still have no solution to the problem.

share|improve this question
    
The first thing I would try is to del both your row objects as well as the cursor objects at the end of the script. Not doing so results in some weird memory-related issues that may be preventing your update your rows. –  Jason Jun 19 '12 at 16:04
1  
Correction: It's a file lock thing, not a memory thing. See the answer to my question here: gis.stackexchange.com/questions/24507/… –  Jason Jun 19 '12 at 16:14
    
+1 - I'm glad you figured out the problem. You might even take your edit and add it as an answer, since the ones provided didn't really catch the problem. I've definitely noticed when working in ArcGIS in general that the locking doesn't seem to be applied consistently. –  Get Spatial Jun 19 '12 at 22:53
    
Having seen your update, I have to wonder if my comment below is perhaps correct. It may not be possible to have nested Update Cursors. I think it would be similar to starting an edit session in ArcMap. You can only edit one location, be that directory, or geodatabase, at a time. Opening the first update cursors locks the location, which causes the second update cursor to fail. –  Get Spatial Jun 24 '12 at 20:22
    
At this point, I would be tempted to contact ESRI Support and see what they say. Then, if they help you solve it, post the answer back here. –  Get Spatial Jun 24 '12 at 20:23
add comment

5 Answers

        del(insprow)

should be:

        del(inspectionRows)
share|improve this answer
add comment

Your issue has to do with the Locking action that happens when an UpdateCursor is called. From the help document:

Summary

The UpdateCursor function creates a cursor that lets you update or delete rows on the specified feature class, shapefile, or table. The cursor places a lock on the data that will remain until either the script completes or the update cursor object is deleted.

What that means to me is that if you call an UpdateCursor in the 4th line, then it puts a lock on the data layers that persists and blocks the UpdateCursor you have inside your loop from working. Since you can update many different parts of the feature with this Cursor, including feature geometry, or attribute information, it stands to reason that having a Linked Table in the Cursor will cause a lock to be placed on both tables involved in the join.

The other factor coming into play is the locking of datasets during editing. If the two featureclasses you are trying to update are located in the same Feature Dataset, then even if they are not linked in the Cursor, they would both be locked. Here is some additional information on Schema Locking.

share|improve this answer
    
To clarify, the feature classes are only linked conceptually. there is not a relationship enforced by the database, and each cursor operates on a different feature class. Additionally, these feature classes are not contained within a feature dataset. –  Caleb Jun 19 '12 at 18:31
    
@Caleb - It isn't specifically mentioned in the documentation, but I wonder if it is simply that you can only have one UpdateCursor open at a time. –  Get Spatial Jun 19 '12 at 18:48
add comment

Now I feel a little silly. I had a map service running which was maintaining a lock on BOTH of the feature classes I was trying to update. I used arcpy.TestSchemaLock to test, and found that it returned false for both feature classes regardless of whether the first was using a searchcursor or an updatecursor. Stopping the service solved my issue. However there is still some funny behavior here that I'd like to understand:

  1. According to the documentation, if the updatecursor can't get an exclusive lock, then it should error out...but my script ran just fine, no errors...why?
  2. Even given that not erroring were a valid behavior, I still should not have been successful with the inner update EVER when the service was running, but it worked fine as long as it was the only updatecursor I was using. Why?
share|improve this answer
add comment

I had a similar problem. The solution I found, was to have only one cursor open at a given moment.

From the Caleb soution, it's look like the versionned data was part of my problem, but for me, unregistering was not an option.

My solution was to collect data in Python variables and organize my code to have only one cursor open at a given moment. So I open a cursor, collect updated values, close the cursor, open another cursor and insert values. In my scenario, I had one updatecursor and an one insertcursor, they were not in the same workspace.

The symptoms were:

  • DeleteField saying that my data were in edit mode (but no edit session in ArcMap opened).
  • If I open an edit session and close it right away, ArcMap ask me to save my edits!
  • Saying "no", my modifications were gone.
share|improve this answer
add comment
up vote -1 down vote accepted

Ok, took a little more investigation, but here's what it boiled down to:

I was using versioned data. Python doesn't work well with versioned data.

Again I'm not really sure why it sometimes worked in the first place, but regardless, after unregistering my data as versioned, the code above ran fine and produced the desired results.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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