Runtime Error: Cannot Acquire Lock

212
2
Jump to solution
04-10-2024 11:33 AM
BrandonMcAlister
Occasional Contributor

So I have this tool I've written which takes geocoded address and selects the parcel they are in then updates the shape coordinates and several fields. However on I keep getting a Runtime Error: Cannot Acquire Lock on line 73 edit.stopEditing(True)

According to ESRI this error happens so infrequently that there are no help docs or solutions for this issue. 

See code below

#Define project
arcpy.SetProgressor("step", "Setting up tool", 0, 100, 1) #sets tool progression label and loading bar

import os #import operating system
import datetime #imports datetime system library

aprx = arcpy.mp.ArcGISProject("Current") #current arcpro project
MP = aprx.activeMap #current open map view
Geocode = MP.listLayers("CSRR_PI_Coords_Geocoded")[0] #create object for Geocoded File
Parcels = MP.listLayers("Parcels (Block and Lot) Data - For Internal Purposes Only - Do Not Distribute")[0] #create parcel object
User = os.getlogin() #Gets windows user names
defaultgdb = aprx.defaultGeodatabase #Gets default geodatabase
arcpy.env.workspace = defaultgdb #Sets workspace equal to default geodatabase
workspace = arcpy.env.workspace #Creates variable to access workspace easily
edit = arcpy.da.Editor(workspace) #creates edit variable

lyrlist = MP.listLayers()
i = 0
while i < len(lyrlist):
if "Multiple_Parcel_PIs" in lyrlist[i].name:
MultiParcel = MP.listLayers("Multiple_Parcel_PIs")[0] #create object for Multiple PI File
break
else:
arcpy.AddMessage("No Multiple Parcel PI feature class was detected.")
i += 1

#Move geocoded points with a point address match and a 100 percent match and did not Tie to parcel centroid
MP.clearSelection() #Clears all selected features in the map
arcpy.management.SelectLayerByAttribute(Geocode, where_clause = "(Addr_type = 'PointAddress' And Score = 100 And Status = 'M' And ProChecker IS NULL) Or ProChecker = 2")
count = arcpy.management.GetCount(Geocode)
if int(str(count)) > 0:
intervaltime = []
now = datetime.datetime.now() #gets time block started
Geocode.definitionQuery = "(Addr_type = 'PointAddress' And Score = 100 And Status = 'M' And ProChecker IS NULL) Or ProChecker = 2"

arcpy.SetProgressorLabel("Moving geocoded points with address match")
arcpy.SetProgressorPosition(1)
cursor = arcpy.da.SearchCursor(Geocode, ["ObjectID"]) #searches through CSRR_PI_Coord_Geocodes and gets all ObjIDs
array = cursor._as_narray() #Turns cursor into an array

i = 0
while i < len(array): #Loops through each spot in the array
loopnow = datetime.datetime.now()
arcpy.management.SelectLayerByAttribute(Geocode, where_clause = "ObjectID = " + str(array[i][0])) #Selects Feature by Object ID in layer CSRR_PI_Coords_Geocoded
arcpy.management.SelectLayerByLocation( #Select the parcel that intersects the feature selected in CSRR_PI_Coords_Geocoded
in_layer = Parcels,
overlap_type = "INTERSECT",
select_features = Geocode,
search_distance = None,
selection_type = "NEW_SELECTION",
invert_spatial_relationship = "NOT_INVERT"
)

#Get parcel centroid and pams pin
Pcursor = arcpy.da.SearchCursor(Parcels, ["SHAPE@TRUECENTROID", "Pams_Pin"]) #Gets parcel centroid and Pams Pin from attribute table
Parray = Pcursor._as_narray() #creates an array for the search cursor
centroid_east = Parray[0][0][0] #Gets centroid easting value
centroid_north = Parray[0][0][1] #Gets centroid northing value
parcel = Parray[0][1] #Creates number string to pass through calculate field

edit.startEditing(False, False) #Starts an editing session
#updates shape Easting and Northing, with parcel centroid
upcursor = arcpy.da.UpdateCursor(Geocode, ["SHAPE@"])
for row in upcursor: #updateRow method only works in for loop
pt = arcpy.Point(centroid_east, centroid_north) #creates an arcpy point with parcel easting and northing
row = [pt] #makes the point equal to row
upcursor.updateRow(row) #Updates feature geometry
del upcursor
parcelcursor = arcpy.da.UpdateCursor(Geocode, ["parcel_data"])
for row in parcelcursor:
row[0] = parcel
parcelcursor.updateRow(row)
del parcelcursor
checkcursor = arcpy.da.UpdateCursor(Geocode, ["ProChecker"])
for row in checkcursor:
row = [4]
checkcursor.updateRow(row)
del checkcursor
edit.stopEditing(True) #Save edits and ends edit session
loopend = datetime.datetime.now()
loopelapse = loopend - loopnow
intervaltime.append(loopelapse.total_seconds())
i += 1
length = len(intervaltime)
total = sum(intervaltime)
mean = total/length
end = datetime.datetime.now()
elapsed = end - now
arcpy.AddMessage(str(len(array)) + " Geocoded address were within a parcel and moved to the centroid. This process took " + str(elapsed) + " with an average of" + str(mean) + " seconds per record.")

#Clears all defintion queries
Geocode.updateDefinitionQueries(None)

#Calculate fields for records that were moved to parcel centroid
arcpy.management.SelectLayerByAttribute(Geocode, where_clause = "ProChecker = 4") #Select points that were moved to parcel centroid
count = arcpy.management.GetCount(Geocode)
arcpy.SetProgressorLabel("Calculating Fields with Batch Update Codes") #changes tool progress label
arcpy.SetProgressorPosition(1) #resets progressor to beginning
if int(str(count)) > 0:
edit.startEditing(False, False)
upcursor = arcpy.da.UpdateCursor(Geocode, ["locational_comments", "updated_by", "coordinate_system_code", "coordinate_source_type_code", "coordinate_source_org_code", "coordinate_source_ref_code", "location_quality_type_code"])
for row in upcursor:
row[0] = "center of site (GIS Parcel Centroid)"
row[1] = str(User)
row[2] = "01"
row[3] = "11"
row[4] = "14"
row[5] = "36"
row[6] = "40"
upcursor.updateRow(row)
del upcursor
edit.stopEditing(True)

#Calculates Date time this feature was updated
arcpy.management.CalculateField( #Calculates Date time this feature was updated
in_table = Geocode,
field = "updated_on",
expression = "datetime.datetime.now()",
expression_type = "PYTHON3",
code_block = "",
field_type = "TEXT",
enforce_domains = "NO_ENFORCE_DOMAINS"
)
else:
arcpy.AddMessage("No fields were calculated, and no PI's had valid Parcel Information")

arcpy.AddMessage("Step 3 completed proceed with manual placement.")

Thanks,
Brandon
0 Kudos
1 Solution

Accepted Solutions
AlfredBaldenweck
MVP Regular Contributor

Make sure the attribute table is closed when running the update cursor.

I kid you not, it will cause issues if you have more than 199 records in your table. (BUG-000113027)

That's going to be the easiest to test, so start there.

View solution in original post

2 Replies
AlfredBaldenweck
MVP Regular Contributor

Make sure the attribute table is closed when running the update cursor.

I kid you not, it will cause issues if you have more than 199 records in your table. (BUG-000113027)

That's going to be the easiest to test, so start there.

BrandonMcAlister
Occasional Contributor

@AlfredBaldenweck I can't believe that worked....

Thanks,
Brandon
0 Kudos