I am getting an error "Cannot acquire a lock" when trying to calculate values in multiple fields.

11184
16
04-19-2018 10:36 AM
BobNoyes
New Contributor III

So, I have created a script that adds 6 fields to a shapefile: Situs_city, Situs_St, Situs_Zip, Latitude, Longitude, and GIS_Acres. Further, the script is set to calculate the values for the Latitude, Longitude, and GIS_Acres fields. The script will work fine until after creating the GIS_acres field. Once this field is created the next step is to calculate and that is when I get an Error 999999: cannot acquire a lock. The weird aspect is once in a while the script will run all the way through just fine... anyway, I am stumped. I am pretty new to creating python scripts. If anyone has a suggestion that would be awesome.

import arcpy
import os

# Step 1  -  Copy new [Taxlots_TEST_DeleteME.shp] from \\cove\Department Shares\Common\Assessor\ArcGIS to E:\STAGING (IKRIT)
#set variables

in_data = "S:\Common\Assessor\ArcGIS\Taxlots_TEST_DeleteME.shp"
Shapefile = "E:\\STAGING\\Taxlots_TEST_DeleteME.shp"
#out_data = "E:\STAGING\Taxlots_TEST_DeleteME.shp"
arcpy.Copy_management(in_data, Shapefile)
print "Step 1 complete"

#Step 2: Add Situs fields
# Create a new field - Situs_City (string, 25)
arcpy.AddField_management(Shapefile, "Situs_City", "TEXT", "","","25","","NULLABLE","NON_REQUIRED","")
print "Step 2a: Add Situs_City complete."

# Create a new field - Situs_St (string, 2)
arcpy.AddField_management(Shapefile, "Situs_St", "TEXT", "#", "#", "2", "#", "NULLABLE", "NON_REQUIRED", "#")
print "Step 2b: Add Situs_St complete."

# Create a new field - Situs_Zip (string, 10)
arcpy.AddField_management(Shapefile, "Situs_Zip", "TEXT", "#", "#", "10", "#", "NULLABLE", "NON_REQUIRED", "#")
print "Step 2c: Add Situs_Zip complete."
print "Step 2: Create situs fields complete."

# Step 3: Create and calculate Latitude and Longitude fields.
latLonRef = "Coordinate Systems\Geographic Coordinate Systems\World\WGS 1984.prj"
Taxlot_shp = "E:\STAGING\Taxlots_TEST_DeleteME.shp"
featureClassesList = Taxlot_shp.split(";")
field_Type = "DOUBLE"
field_precision_1 = 12
field_scale_1 = 8

for featureClass in featureClassesList:
 arcpy.AddMessage("Calculating XY coordinates for: " + featureClass)
 arcpy.AddField_management(featureClass, "Latitude", field_Type, field_precision_1, field_scale_1)
 arcpy.AddField_management(featureClass, "Longitude", field_Type, field_precision_1, field_scale_1)
 rows = arcpy.UpdateCursor(featureClass, "", latLonRef)
for row in rows:
 feat = row.getValue("shape")
 cent = feat.centroid
                # To get the polygon area: cent = feat.area
 row.Latitude = cent.Y
 row.Longitude = cent.X
 rows.updateRow(row)
  #arcpy.AddMessage(str(lat) + ", " + str(lon))
print "Step 3: Add Lat and Long complete"

# Step 4: Create a new field - GIS_Acres (Double, 15, 3)
Shapefile3 = "E:\STAGING\Taxlots_TEST_DeleteME.shp"
#Set local variables
field_Name = "GIS_Acres"
field_Type = "DOUBLE"
field_Precision = 15 #total number of digits stored
field_Scale = 4 #number of decimals places

arcpy.AddField_management(Shapefile3, field_Name, field_Type, field_Precision, field_Scale)
arcpy.CalculateField_management(Shapefile3, field_Name, '!SHAPE.area@ACRES!', "PYTHON_9.3")
print "Step 4: Calculate acres complete"

print "Congratulations! You have completed adding fields to to the Taxlots feature class. "

0 Kudos
16 Replies
DanPatterson_Retired
MVP Esteemed Contributor

could be due to the fact that the Shapefile variable and the Taxlot_shp are referencing the same file.  Try deleting references to them or just reuse the variable name and make sure that that shapefile isn't within the 'for featureclasses' loop because being referenced several times within one script will certainly cause locks.

BobNoyes
New Contributor III

I tried doing the script with a single variable for the whole script and had the same problem and thought that if I recalled the file at each stage it might get rid of the lock. Sounds like I can revert back to that. I am not sure how to eliminate multiple uses of the shapefile in the loop. Suggestions?

Bob Noyes

GIS Analyst

Josephine County

541-474-5244

GIS Webpage<http://www.co.josephine.or.us/SectionIndex.asp?SectionID=129>

rnoyes@co.josephine.or.us<mailto:rnoyes@co.josephine.or.us>

“A road map always tells you everything, except how to refold it<http://thinkexist.com/quotation/a_road_map_always_tells_you_everything_except_how/156219.html>” unknown

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Hi Bob,

My guess is it's something with your cursor that is placing a lock.  Instead of calculating the Latitude/Longitude I would use the Add XY Coordinates function.  This will create two fields POINT_X and POINT_Y with the latitude and longitude.  You can then rename these fields use the Rename function. 

If your data is not in a Geographic Coordinate System you can set the Output Coordinate System Environment Variable.  Ex:

arcpy.env.outputCoordinateSystem = arcpy.SpatialReference(4326)

I would also recommend working with a feature class than a shapefile.  This provides much more functionality.  A couple other notes.  If you are going to use a cursor, use the arcpy.da.UpdateCursor.  These cursors are 10x faster.

I also wanted to give you the following link that discusses how to post code.  It makes it much easier for others to read. 

BobNoyes
New Contributor III

I will check out your suggestions. I did try initially copying the shapefile to a feature class but the lat long function took over a half hour to calculate and I would get the error for acquiring a lock. When trying the arcpy.da.UpdateCursor<https://community.esri.com/external-link.jspa?url=http%3A%2F%2Fdesktop.arcgis.com%2Fen%2Farcmap%2F10.3%2Fanalyze%2Farcpy-data-access%2Fupdatecursor-class.htm> I got a sql error. Perhaps that was because I was working with a shapefile at that point? Anyway, thanks for the link to posting code and the suggestions.

Bob Noyes

GIS Analyst

Josephine County

541-474-5244

GIS Webpage<http://www.co.josephine.or.us/SectionIndex.asp?SectionID=129>

rnoyes@co.josephine.or.us<mailto:rnoyes@co.josephine.or.us>

“A road map always tells you everything, except how to refold it<http://thinkexist.com/quotation/a_road_map_always_tells_you_everything_except_how/156219.html>” unknown

0 Kudos
BobNoyes
New Contributor III

Upon further investigation, i.e., looking at the link you sent, that code if for point and I am trying to get the xy coordinates for polygon centroids.

Bob Noyes

GIS Analyst

Josephine County

541-474-5244

GIS Webpage<http://www.co.josephine.or.us/SectionIndex.asp?SectionID=129>

rnoyes@co.josephine.or.us<mailto:rnoyes@co.josephine.or.us>

“A road map always tells you everything, except how to refold it<http://thinkexist.com/quotation/a_road_map_always_tells_you_everything_except_how/156219.html>” unknown

0 Kudos
RichardFairhurst
MVP Honored Contributor

You have opened an UpdateCursor and looped through the records which is applying a lock to your data before you do the calculation and have not closed the cursor.  You need to delete the row variable at the end of the statements inside the for loop and delete the rows variable outside of the for loop after the for loop is completed.  You also should have used the da UpateCursor, which performs much quicker and includes a With syntax that closes the cursor automatically once the cursor has been read or statements are executed at the same indent level as the With declaration.  If this was my code, I would restructure the code to do all of the AddField operations before doing any updateCursor or Field Calculation operations to be safe.

BobNoyes
New Contributor III

Thanks for the feedback. Sounds like I need to revert back to coping from a shapefile first then doing the other processes. I mentioned above that using the arcpy.da.updateCurser I got an error but I am wondering if that is due to my working with a shapefile.

Bob Noyes

GIS Analyst

Josephine County

541-474-5244

GIS Webpage<http://www.co.josephine.or.us/SectionIndex.asp?SectionID=129>

rnoyes@co.josephine.or.us<mailto:rnoyes@co.josephine.or.us>

“A road map always tells you everything, except how to refold it<http://thinkexist.com/quotation/a_road_map_always_tells_you_everything_except_how/156219.html>” unknown

0 Kudos
BobNoyes
New Contributor III

Your suggestion to create the fields first seem like a good plan so I have done that. However, since the script to calculate the lat and long for the polygon centroids was one I stole I am not quite sure how to revise it to read the created fields. Any ideas?

import arcpy
import os

#Step 1: Copy S:\Common\Assessor\ArcGIS\Taxlots_TEST_DeleteME.shp to Joco A assessor
#Set Variables
in_data = "S:\Common\Assessor\ArcGIS\Taxlots_TEST_DeleteME.shp"
out_database = "Database Connections/jocoA_Staging.sde/jocoA_Staging.DBO.Assessor"
# Copy 
arcpy.FeatureClassToGeodatabase_conversion(in_data,out_database)
print "Step 1: Copy complete."

#Step 2: Add Situs fields
#Set variables
out_fc = "Database Connections/jocoA_Staging.sde/jocoA_Staging.DBO.Assessor/jocoA_Staging.DBO.Taxlots_TEST_DeleteME"
# Step 2a: Create a new field - Situs_City (string, 25)
arcpy.AddField_management(out_fc, "Situs_City", "TEXT", "","","25","","","")
print "Step 2a: Add Situs_City complete."

# Create a new field - Situs_St (string, 2)
arcpy.AddField_management(out_fc, "Situs_St", "TEXT", "", "", "2", "", "", "")
print "Step 2b: Add Situs_St complete."

# Create a new field - Situs_Zip (string, 10)
arcpy.AddField_management(out_fc, "Situs_Zip", "TEXT", "", "", "10", "", "", "")
print "Step 2c: Add Situs_Zip complete."
print "Step 2: adding the Situs fields has been successful!"

# Step 3a: add Latitude (double, 12, 8)
arcpy.AddField_management(out_fc, "Latitude", "DOUBLE", "12", "8", "", "", "", "")
print "Step 3a: Add Latitude is completed."

# # Step 3b: add Longitude (double, 12, 8)
arcpy.AddField_management(out_fc, "Longitude", "DOUBLE", "12", "8", "", "", "", "")
print "Step 3b: Add Longitude is completed"
print "Step 3: adding the Latitude and Longitude fields has been successful!"

# # Step 4a: add GIS_Acres (double, 15, 4)
arcpy.AddField_management(out_fc, "GIS_Acres", "DOUBLE", "15", "4", "", "", "", "")
print "Step 4: Add GIS_Acres field completed."

#Step 5: Calculate GIS_Acres
arcpy.CalculateField_management(out_fc, "GIS_Acres", '!SHAPE.area@ACRES!', "PYTHON_9.3")
print "Step 5 Acres have been calculated."



# Step 4: calculate Latitude and Longitude fields.
latLonRef = "Coordinate Systems\Geographic Coordinate Systems\World\WGS 1984.prj"

featureClassesList = out_fc.split(";")
field_Type = "DOUBLE"
field_precision_1 = 12
field_scale_1 = 8

for featureClass in featureClassesList:
 arcpy.AddMessage("Calculating XY coordinates for: " + featureClass)
 arcpy.AddField_management(featureClass, "Latitude", field_Type, field_precision_1, field_scale_1)
 arcpy.AddField_management(featureClass, "Longitude", field_Type, field_precision_1, field_scale_1)
 rows = arcpy.da.UpdateCursor(featureClass, "", latLonRef)
for row in rows:
 feat = row.getValue("shape")
 cent = feat.centroid
                # To get the polygon area: cent = feat.area
 row.Latitude = cent.Y
 row.Longitude = cent.X
 rows.updateRow(row)
  #arcpy.AddMessage(str(lat) + ", " + str(lon))
print "Step 4: Add Lat and Long complete"


print "Congratulations! You have completed adding and calculating the necessary fields to the Taxlots feature class. "‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
RebeccaStrauch__GISP
MVP Esteemed Contributor

In you step 3a and 3b you are adding the Latitude and Longitude fields, so you should not need to add them again in lines 57/58.  But I also do not think you need to have a cursor to get this info sine it looks like you out_fc and therefore your featureClassesList is only one feature class.  Is that correct?  Or do you plan to have a list of FC to process at come point?  if you will eventually have a list of fc that you will input, then don't add them in 3a and 3b....howevere, you may not need to add them at all..

If you use the tool Add XY Coordinates—Help | ArcGIS for Desktop  Jake recommended, that  

      "Adds the fields POINT_X and POINT_Y to the point input features and calculates their values"

But you said your features are polygons.

 

I think a better option for you if you are looking for the centroids is to use this tool

Add Geometry Attributes—Help | ArcGIS Desktop   which

Adds new attribute fields to the input features representing the spatial or geometric characteristics and location of each feature, such as length or area and x-, y-, z-, and m-coordinates.

Syntax:
AddGeometryAttributes_management (Input_Features, Geometry_Properties, {Length_Unit}, {Area_Unit}, {Coordinate_System})

There is a long list of "Geometry_Properties" types that you can request.    These is no need to "calculate" these fields if there is a tools that will do it for you, unless there is a reason (school assignment or if input to another tool step that will need this).

One comment about the AddGeometryAttibutes tool that I ran into in 10.2.2, if you cal a projected coord to geography and then back, there may be some small round off error.  Not significant, but for our Albers to geometry to Albers (I won't go into why I had to do this), there was a slight different.  Nothing that was measurable for what we were doing (small planes).

Hope this helps.