1

The following script works to update coordinates in my ArcGIS feature class, but if I run it twice in a row from ArcMap on the same geodatabase feature class, I get a "RuntimeError: Unexpected Operation[outputZoneTrack FeatureClass name]" error on the "updateCursor.updateRow(row)". If I run it on a dataset, then run it on a different dataset, I can then re-run it on the first dataset again with no problem. I just can't run it on the same dataset twice in a row. Why does this error occur when I run the script twice in a row on the same dataset?

outputZoneTrack = "C:\\Temp\\geodatabase.gdb\\ozt"
outputWorkspace = os.path.split(outputZoneTrack)[0]
outputZoneTrackName = os.path.split(outputZoneTrack)[1]

arcpy.env.overwriteOutput = True
if arcpy.Exists(outputZoneTrack):
    arcpy.Delete_management(outputZoneTrack)

spatial_reference = arcpy.SpatialReference(4326) #Use WGS84 so coordinates are calculated in Lat/Long
with arcpy.da.UpdateCursor(outputZoneTrack, ["ZSTARTLAT", "ZSTARTLON", "ZENDLAT", "ZENDLON", "SHAPE@"], "", spatial_reference) as updateCursor:
    for row in updateCursor:

        row[0] = row[4].firstPoint.Y
        row[1] = row[4].firstPoint.X
        row[2] = row[4].lastPoint.Y
        row[3] = row[4].lastPoint.X
        updateCursor.updateRow(row)

mxd = arcpy.mapping.MapDocument("CURRENT")
    for lyr in arcpy.mapping.ListLayers(mxd):
        if lyr.name == "Segment Oil Zones":
            if lyr.supports("DATASOURCE"):
                lyr.replaceDataSource(outputWorkspace, "FILEGDB_WORKSPACE", outputZoneTrackName, True)
                lyr.name = "Segment Oil Zones"
                lyr.visible = True
                arcpy.AddMessage("\nOiling Zone Snapped to ACP Segments: ON\n")
                arcpy.RefreshTOC()

Note - this problem only occurs if the script is run from ArcMap and the feature class is loaded within the ArcMap TOC - I can run it multiple times in a row on the same dataset from ArcCatalog.

  • 1
    Is that the entire error message? Is it failing on updateCursor.updateRow(row)? Please edit your question to include any updates – Midavalo Feb 14 '17 at 20:05
  • 1
    A full error message should include the line number. – PolyGeo Feb 14 '17 at 20:27
  • 4
    How are you opening a cursor on outputZoneTrack when you are deleting it a few lines prior? – Paul Feb 14 '17 at 22:37
  • 1
    It seems to me there is more going on in your script (before or after the cursor) that is holding onto the feature class that you're modifying. What does your script do after the cursor? Have you tried running just the snippet you've pasted in your question? What does that do? – Midavalo Feb 15 '17 at 2:38
  • 1
    When you run it in ArcMap is it creating a new layer in your TOC? Or are you running it on an existing layer in your TOC? – Midavalo Feb 15 '17 at 2:38
1

UPDATED. This works. The real issue this script could not be run twice in a row on the same feature class appears to have something to do with being locked by the layer in the current MXD after the 1st run. So I made the script to change the data path on that layer when running, then change it back at the end of the script.

arcpy.env.overwriteOutput = True
if arcpy.Exists(outputZoneTrack):
    arcpy.Delete_management(outputZoneTrack)

outputZoneTrack = "C:\\Temp\\geodatabase.gdb\\ozt"
outputWorkspace = os.path.split(outputZoneTrack)[0]
outputZoneTrackName = os.path.split(outputZoneTrack)[1]

mxd = arcpy.mapping.MapDocument("CURRENT")
for lyr in arcpy.mapping.ListLayers(mxd):
    if lyr.name == "Segment Oil Zones":
        if lyr.supports("DATASOURCE"):
            lyr.replaceDataSource(outputWorkspace, "FILEGDB_WORKSPACE", outputZoneTrackName + "_Temp", True)
            lyr.name = "Segment Oil Zones TEMP"
            lyr.visible = False
            arcpy.AddMessage("\nOiling Zone Snapped to ACP Segments: OFF\n")
            arcpy.RefreshTOC()



spatial_reference = arcpy.SpatialReference(4326) #Use WGS84 so coordinates are calculated in Lat/Long
with arcpy.da.UpdateCursor(outputZoneTrack, ["ZSTARTLAT", "ZSTARTLON", "ZENDLAT", "ZENDLON", "SHAPE@"], "", spatial_reference) as updateCursor:
    for row in updateCursor:

        row[0] = row[4].firstPoint.Y
        row[1] = row[4].firstPoint.X
        row[2] = row[4].lastPoint.Y
        row[3] = row[4].lastPoint.X
        updateCursor.updateRow(row)

mxd = arcpy.mapping.MapDocument("CURRENT")
    for lyr in arcpy.mapping.ListLayers(mxd):
        if lyr.name == "Segment Oil Zones TEMP":
            if lyr.supports("DATASOURCE"):
                lyr.replaceDataSource(outputWorkspace, "FILEGDB_WORKSPACE", outputZoneTrackName, True)
                lyr.name = "Segment Oil Zones"
                lyr.visible = True
                arcpy.AddMessage("\nOiling Zone Snapped to ACP Segments: ON\n")
                arcpy.RefreshTOC()
  • 2
    row is a tuple, which is immutable. Add row = list(row) directly after the for loop and it should work without temp variable. – Paul Feb 16 '17 at 23:19
  • @Paul You are right, that does work and is more elegant. That being the case, why would the script run fine the first time and only crash when being re-run consecutively on the same feature class? – spaine Feb 16 '17 at 23:34
  • I have no idea. Python should be throwing TypeError unless you had the variable row floating around from earlier. – Paul Feb 16 '17 at 23:45
  • It turns out that tuple was not related to the error - it had something to do with the layer in the MXD locking the feature class after the first time it was run. I've updated the answer accordingly. – spaine Feb 17 '17 at 20:56
0

You are attempting to use outputZoneTrack before it is defined. Try defining it before testing if it exists and before attempting to delete it. (I'm not certain this will fix your issue, but it does appear to be an issue that needs fixing.)

Ie, replace this:

arcpy.env.overwriteOutput = True
if arcpy.Exists(outputZoneTrack):
    arcpy.Delete_management(outputZoneTrack)

outputZoneTrack = "C:\\Temp\\geodatabase.gdb\\ozt"

with this:

outputZoneTrack = "C:\\Temp\\geodatabase.gdb\\ozt"

arcpy.env.overwriteOutput = True
if arcpy.Exists(outputZoneTrack):
    print "Deleting {}".format(outputZoneTrack)
    arcpy.AddMessage("Deleting {}".format(outputZoneTrack))
    arcpy.Delete_management(outputZoneTrack)

(I've also added debug lines, print and AddMessage, which will at least make it clear when it's actually running Delete_management.)

  • 2
    This may be the answer (I don't know) however it does appear that the code is part of a much larger script (see error message referring to line 178), and from the comments the asker has added the outputZoneTrack = "C:\\Temp\\geodatabase.gdb\\ozt" line for clarity – Midavalo Feb 15 '17 at 7:07
0

You are using an arcpy.da.cursor. They are notorious for putting schema locks on feature classes. You will need to delete your cursor at the end of the iteration to free up the schema lock.

 del row
 del updateCursor

You may just need to delete the cursor not the row.

  • I've tried that, it had no effect. Also, putting the cursor within a with statement should prevent that lock from persisting. – spaine Feb 17 '17 at 21:14
  • You shouldn't need to use del if you're using with statements. – Paul Feb 17 '17 at 21:53

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.