Select to view content in your preferred language

arcpy.management.CalculateField running into "Cannot acquire a lock" error

1372
7
Jump to solution
10-21-2024 11:13 AM
MichaelMarlatt1
Occasional Contributor

Hello,

I have a python notebook that I've been running in Pro v3.0 that compares a handful of point feature classes to two different versions of a polygon feature class and tells me which points are not in the same polygon in both versions.  

The problem I am having is after adding columns to the point feature classes (via arcpy.management.AddField), I keep getting a "Cannot acquire a lock" error when I try to calculate values into those fields.  These feature classes are all in a file geodatabase that nobody else is using except me.  

What do I need to do between the first CalculateField and the second to get this to work?  It is the same feature class involved both times.

I use CalculateField many times elsewhere in the notebook but after arcpy.management.SelectLayerByLocation (or ByAttribute).  This only is happening when it follows .AddField.

Here are the relevant sections of the notebook:

 

#adding the fields
arcpy.management.AddField(NewDlnLayer,DlnChangedField,"TEXT",field_length=1)
arcpy.management.AddField(NewDlnLayer,DlnOnParcelBorder,"TEXT",field_length=1)

#Calculating values into the fields

arcpy.management.CalculateField(NewDlnLayer,DlnChangedField,"'N'","PYTHON3")
arcpy.management.CalculateField(NewDlnLayer,DlnOnParcelBorder,"'N'","PYTHON3") #IT'S BEEN FAILING HERE

Thank you,

Mike

 

0 Kudos
1 Solution

Accepted Solutions
HaydenWelch
MVP Regular Contributor

I'd just use UpdateCursor objects for this task:

import arcpy

NewDlnLayer = "path/to/your/layer"
DlnChangedField = "DlnChangedField"
DlnOnParcelBorder = "DlnOnParcelBorder"

fields = [
    [
        DlnOnParcelBorder, #field name
        "TEXT",            #field type
        1                  #field length
    ],
    [
        DlnOnParcelBorder,
        "TEXT",
        1
    ],
]
#adding the fields
arcpy.management.AddFields(NewDlnLayer, fields)

#Calculating values into the fields using UpdateCursor
with arcpy.da.UpdateCursor(NewDlnLayer, [DlnChangedField, DlnOnParcelBorder]) as cursor:
    for row in cursor:
        row = ['N', 'N']
        cursor.updateRow(row)

 

If you keep having issues, you could try using arcpy.da.Editor() context and checking the exceptions raised?

View solution in original post

7 Replies
AlfredBaldenweck
MVP Regular Contributor

If the attribute tables are open when you run your code, close them and see if that fixes it.

0 Kudos
MichaelMarlatt1
Occasional Contributor

I read that somewhere here and I made sure to have the tables closed.  It didn't make a difference unfortunately.

0 Kudos
DanPatterson
MVP Esteemed Contributor

Try

Add Fields (multiple) (Data Management)—ArcGIS Pro | Documentation

although I suspect that adding the fields in two separate instances wouldn't be the cause of the lock


... sort of retired...
0 Kudos
MichaelMarlatt1
Occasional Contributor

Hi Dan,

I tried using .AddFields.  It does its work faster than .AddField, but I am still having the same problem when trying to use .CalculateField afterwards.  I am now looking for some sort of a .Save() command that needs to be used after tools like .AddField, .AddFields, or .CalculateField that updates the feature class.  

So far ESRI's documentation is not helping much.  The page for the error is especially useless: 160706: Cannot acquire a lock.—ArcGIS Pro | Documentation

I'll keep digging.

 

Mike

0 Kudos
BrandonMcAlister
Frequent Contributor

@MichaelMarlatt1 

Do you have a workspace set and is your NewDlnLayer referencing a map object or a workspace object?

More so how are you declaring that variable? It could be as simple as redeclaring your variable between the two operations but I have not had to do that before when running these commands. 

I do regularly use edit operations anytime I make changes to feature classes or map layers. It is just an added layer of protection I like to use to ensure my edits get applied properly. Check out this link below I think its the .Save() you were looking for:

https://pro.arcgis.com/en/pro-app/latest/arcpy/data-access/editor.htm

Thanks,
Brandon
MichaelMarlatt1
Occasional Contributor

I'll take a look at the editor class, thank you.

I'm not sure about the workspace but I think I'm working from a map object.  Here are the firs three cells of the notebook (the problem I'm having is ocurring in the third cell).

First Cell:

 

'''Get set up'''
import arcpy
project = arcpy.mp.ArcGISProject("CURRENT")
#print("Map's name is " + project.listMaps()[0].name)
m = project.listMaps()[0] #Get the map
CurrentDlnLayer = m.listLayers('esriopsgis.GISOPSWRITER.DLN_NWD')[0]
CurrentParcelLayer = m.listLayers('GISOPSWRITER.MergedParcels')[0]
CurrentPoleLayer = m.listLayers('esriopsgis.GISOPSWRITER.Pole_ALL_NWD')[0]
CurrentSubstructLayer = m.listLayers('esriopsgis.GISOPSWRITER.Substruct_NWD')[0]
CurrentSubBoxLayer = m.listLayers('esriopsgis.GISOPSWRITER.Subbox_NWD')[0]

OldDate = '20241025'  #*************** CHANGE THIS TO MATCH THE DATE OF THE "OLD" DATA, YYYYmmdd
OldDlnLayer = m.listLayers('DLN_' + OldDate)[0] 
OldParcelLayer = m.listLayers('MergedParcels_' + OldDate)[0] 
OldPoleLayer = m.listLayers('Pole_ALL_NWD_' + OldDate)[0]
OldSubstructLayer = m.listLayers('Substruct_NWD_' + OldDate)[0]
OldSubBoxLayer = m.listLayers('Subbox_NWD_' + OldDate)[0]

 

Second Cell: 

 

'''Copy DLN, Pole, Substruct, Subbox, and MergedParcels feature classes to project gdb. Creating a snapshot.'''
from datetime import date
todays_date = date.today().strftime("%Y%m%d") #format current date as yyyymmdd
#print(todays_date)
#create names of new layers
DlnNewName = 'DLN_' + todays_date
ParcelsNewName = 'MergedParcels_' + todays_date
PolesNewName = 'Pole_ALL_NWD_' + todays_date
SubstructNewName = 'Substruct_NWD_' + todays_date
SubBoxNewName = 'Subbox_NWD_' + todays_date

#copy layers
arcpy.conversion.FeatureClassToFeatureClass(CurrentDlnLayer,project.defaultGeodatabase,DlnNewName)
arcpy.conversion.FeatureClassToFeatureClass(CurrentParcelLayer,project.defaultGeodatabase,ParcelsNewName)
arcpy.conversion.FeatureClassToFeatureClass(CurrentPoleLayer,project.defaultGeodatabase,PolesNewName) 
arcpy.conversion.FeatureClassToFeatureClass(CurrentSubstructLayer,project.defaultGeodatabase,SubstructNewName)
arcpy.conversion.FeatureClassToFeatureClass(CurrentSubBoxLayer,project.defaultGeodatabase,SubBoxNewName)

 

 

Third cell: (the error has been occurring on line 23)

 

'''Add fields to DLN, MergedParcel, Pole, Substruct, Subbox copies and calculate them to 'N'
***Only need to do this with the NEW parcels and DLNs '''
NewDlnLayer = m.listLayers(DlnNewName)[0]
DlnChangedField = 'dlg_geom_changed'
DlnOnParcelBorder = 'dlg_on_parcel_border'

NewParcelLayer = m.listLayers(ParcelsNewName)[0]
ParcelChangedField = 'parcel_geom_changed'

NewPoleLayer = m.listLayers(PolesNewName)[0]
PoleChangedField = 'pole_geom_changed'
PoleOnParcelBorder = 'pole_on_parcel_border'

NewSubstructLayer = m.listLayers(SubstructNewName)[0]
SubstructChangedField = 'substruct_geom_changed'
SubstructOnParcelBorder = 'substruct_on_parcel_border'

NewSubboxLayer = m.listLayers(SubBoxNewName)[0]
SubboxChangedField = 'subbox_geom_changed'
SubboxOnParcelBorder = 'subbox_on_parcel_border'

arcpy.management.AddField(NewDlnLayer,DlnChangedField,"TEXT",field_length=1)
arcpy.management.CalculateField(NewDlnLayer,DlnChangedField,"'N'","PYTHON3")
arcpy.management.AddField(NewDlnLayer,DlnOnParcelBorder,"TEXT",field_length=1)
arcpy.management.CalculateField(NewDlnLayer,DlnOnParcelBorder,"'N'","PYTHON3")

arcpy.management.AddField(NewParcelLayer,ParcelChangedField,"TEXT",field_length=1)
arcpy.management.CalculateField(NewParcelLayer,ParcelChangedField,"'N'","PYTHON3")

arcpy.management.AddField(NewPoleLayer,PoleChangedField,"TEXT",field_length=1)
arcpy.management.CalculateField(NewPoleLayer,PoleChangedField,"'N'","PYTHON3")
arcpy.management.AddField(NewPoleLayer,PoleOnParcelBorder,"TEXT",field_length=1)
arcpy.management.CalculateField(NewPoleLayer,PoleOnParcelBorder,"'N'","PYTHON3")

arcpy.management.AddField(NewSubstructLayer,SubstructChangedField,"TEXT",field_length=1)
arcpy.management.CalculateField(NewSubstructLayer,SubstructChangedField,"'N'","PYTHON3")
arcpy.management.AddField(NewSubstructLayer,SubstructOnParcelBorder,"TEXT",field_length=1)
arcpy.management.CalculateField(NewSubstructLayer,SubstructOnParcelBorder,"'N'","PYTHON3")

arcpy.management.AddField(NewSubboxLayer,SubboxChangedField,"TEXT",field_length=1)
arcpy.management.CalculateField(NewSubboxLayer,SubboxChangedField,"'N'","PYTHON3")
arcpy.management.AddField(NewSubboxLayer,SubboxOnParcelBorder,"TEXT",field_length=1)
arcpy.management.CalculateField(NewSubboxLayer,SubboxOnParcelBorder,"'N'","PYTHON3")

 

 

0 Kudos
HaydenWelch
MVP Regular Contributor

I'd just use UpdateCursor objects for this task:

import arcpy

NewDlnLayer = "path/to/your/layer"
DlnChangedField = "DlnChangedField"
DlnOnParcelBorder = "DlnOnParcelBorder"

fields = [
    [
        DlnOnParcelBorder, #field name
        "TEXT",            #field type
        1                  #field length
    ],
    [
        DlnOnParcelBorder,
        "TEXT",
        1
    ],
]
#adding the fields
arcpy.management.AddFields(NewDlnLayer, fields)

#Calculating values into the fields using UpdateCursor
with arcpy.da.UpdateCursor(NewDlnLayer, [DlnChangedField, DlnOnParcelBorder]) as cursor:
    for row in cursor:
        row = ['N', 'N']
        cursor.updateRow(row)

 

If you keep having issues, you could try using arcpy.da.Editor() context and checking the exceptions raised?