arcpy UpdateCursor "cannot acquire a lock"

4705
4
05-20-2012 08:29 PM
UrbisMelbourne
New Contributor II
I'm pretty new to Python, and I'm trying to put together a script which will, after doing a bunch of other stuff, update a column conditionally based on the contents of another column.  The relevant code is:

rows = arcpy.UpdateCursor(r"C:\TEMP\storesgathered.shp")
for row in rows:
    if row.getValue("CenType") == "REG":
        arcpy.CalculateField_management(r"C:\TEMP\storesgathered.shp", "Adj_X", 8)
    else:
        arcpy.CalculateField_management(r"C:\TEMP\storesgathered.shp", "Adj_X", 9)
    rows.updateRow(row)
del row, rows


So basically it's supposed to look at each row in "CenType", check if it equals "REG", and calculate out "Adj_X" with the relevant value.  The calculate field values for "Adj_X" are just dummy values at this point, to see if I can get it working.  The final script will have a bunch of elifs as well, to account for all of the possible values in "CenType".

The problem is, when I run it, I get this:

Runtime error <class 'arcgisscripting.ExecuteError'>: ERROR 999999: Error executing function. Cannot acquire a lock. Cannot acquire a lock. [The table storesgathered.shp is being written by another process.] Failed to execute (CalculateField).


This is a really stubborn lock too - removing the layer from the TOC isn't enough; I need to exit all the way out of ArcMap to release it.  I've tried running the snippet of code externally from IDLE as well, but the shapefile still gets locked.  I've even tried exporting the shapefile to an in_memory entity, but it still gets locked.

I'm sort of out of ideas here.  Is there something obvious I'm doing wrong, or is there another approach that will get me the same results?
Tags (2)
0 Kudos
4 Replies
BruceNielsen
Occasional Contributor III
The short answer to your problem is that you can't use CalculateField on the same data that you're already accessing through an update cursor. It isn't appropriate in this context anyway; CalculateField is meant for performing the same calculation for every row in the layer. Here is the logic you should use for changing the attributes in an update cursor:
for row in rows:
    if row.getValue("CenType") == "REG":
        row.Adj_X = 8)
    else:
        row.Adj_X = 9)
    rows.updateRow(row)
RebeccaStrauch__GISP
MVP Emeritus

Bruce, you may want to remove the extra  )  at the end of row 3 and 5.  For future viewers.

0 Kudos
markdenil
Occasional Contributor III
Don't use CalculateField_management inside the cursor.

CalculateField_management essentially sets up a new cursor on the file: your file, however, is already locked by your UpdateCursor named rows.

You already have the row in hand, and you can directly update the value in any of its fields:

if row.getValue("CenType") == "REG": row.Adj_X = 8
0 Kudos
UrbisMelbourne
New Contributor II
Awesome, works a treat, thanks guys.
0 Kudos