TableToNumPyArray creates schema lock in File Geodatabase

326
1
10-12-2023 12:52 PM
isburns
New Contributor III

I'm using ArcGIS Pro 3.1.2. Calling TableToNumPyArray or FeatureClassToNumPyArray creates a schema lock on the File Geodatabase containing the feature class or table used as input to the function when the code is executed in a Jupyter Notebook in a standalone environment. It also creates a schema lock when executed via a standalone Python window. This does not happen when the code is executed from a Jupyter Notebook run inside of ArcGIS Pro, or from the Python Console in ArcGIS Pro. The only method I found for releasing the schema lock is restarting the Kernel or exiting Python in the standalone window.

This seems like a bug since it doesn't occur when the code is executed inside Pro. Is there a way to release the schema lock that is unadvertised?

Provide a path to your data and a valid field name and the code below will produce locks in your geodatabase when executed in Jupyter Notebooks outside of Pro.

import arcpy
import numpy
tbl = r"path to your table here"
fld = "a field in your table"
nulls_bool = False # Tested with both True and False, doesn't matter
arr = arcpy.da.TableToNumPyArray(tbl, fld, skip_nulls=nulls_bool)

 

0 Kudos
1 Reply
isburns
New Contributor III

This appears to be a wider problem with the arcpy.da module. As documented in this post, arcpy.da.Describe() also creates a schema lock in a file geodatabase when a layer is used as the argument. I am hoping this topic gets some attention and is ultimately addressed without having to resort to workarounds, but in my case and in the case of using arcpy.da.Describe(), I found a workaround using arcpy.management.GetCount().

In my case, I was able to call GetCount with the path to a table in the file geodatabase that has the lock from using the arcpy.da module and the lock was released. Note that I was using paths to the data and not arcpy.mp.Layer objects.

In the post referenced above, that wasn't quite enough. As mentioned in that post, using arcpy.Describe() with a path as the argument was the workaround. Using arcpy.Describe() with a Layer object as the argument still created a schema lock, and using arcpy.da.Describe() with a path as the argument also resulted in a schema lock. Calling arcpy.management.GetCount()released the lock only when arcpy.da.Describe() was used with a path as the argument; it did not work when the Layer object was passed as the argument in either the arcpy.Describe() or arcpy.da.Describe() cases.

I've included a code sample below that demonstrates the schema locks and partial success in releasing them for arcpy.da.Describe(). Note that you'll have to reset the Python environment between cases 3 and 4 since case 3 doesn't release the lock.

Edit: I've included a 5th case demonstrating lock files being created by the Layer object without the use of the arcpy.da module. Note again that the Python environment should be reset between cases 4 and 5.

 

import arcpy
aprx_path = r"path to a Pro project with a map containing feature layers in a file gdb"
aprx = arcpy.mp.ArcGISProject(aprx_path)
m = aprx.listMaps()[0]
lyrs = m.listLayers()
lyr = lyrs[0]

# case 1 - lock created by arcpy.da.Describe() with a path as the argument
# lock released using arcpy.management.GetCount() with a path as the argument
desc1 = arcpy.da.Describe(lyr.dataSource)
result1 = arcpy.management.GetCount(lyr.dataSource)

# case 2 - lock NOT created using arcpy.Describe() with a path as the argument
desc2 = arcpy.Describe(lyr.dataSource)

# case 3 - lock created by arcpy.da.Describe() with a Layer object as the argument
# lock NOT released using arcpy.management.GetCount() with a path as the argument
desc3 = arcpy.da.Describe(lyr)
result3 = arcpy.management.GetCount(lyr.dataSource)

# case 4 - lock created by arcpy.Describe() with a Layer object as the argument
# lock NOT released using arcpy.management.GetCount() with a path as the argument
desc4 = arcpy.Describe(lyr)
result4 = arcpy.management.GetCount(lyr.dataSource)

# case 5 - lock created by using arcpy.management.GetCount() with a Layer object as the argument
# lock NOT released using arcpy.management.GetCount() with a path as the argument
result5 = arcpy.management.GetCount(lyr)
del result5 # this does remove one of two lock files from the gdb
result6 = arcpy.management.GetCount(lyr.dataSource)

 

 

0 Kudos