I wrote a script tool for someone to allow them to clean all whitespace errors (leading/trailing spaces, 2+ consecutive white spaces, convert empty strings to nulls), and aside from one issue it works fantastically. The issue is that, when you run the tool against a layer in ArcGIS Pro and you have that layers attribute table open, the tool cannot acquire a lock. If you close the attribute table and run the tool against the same layer in the table of contents, it runs fine.

I'm wondering if I did something wrong, or if opening the table view actually is causing this locking error and there's no way around it?

This script has much room for improvement and was created out of necessity in about an hour, feel free to point out other issues as you see fit but really my main goal is to figure out why this is causing a locking issue.

Tool:               <Whitespace Cleaner>
Source Name:        <WhitespaceCleaner>
Version:            <2.7>
Author:             <John Ehlen>
Usage:              <Toolbox interface>
Required Arguments: <Input Feature>

Description:        <Allows user to select a feature class, and one or more target fields to clean duplicate whitespace, line breaks, and new line characters>
import arcpy, os, sys, re

def ScriptTool(parameter0, parameter1):
    input_Feature = parameter0
    dataType = arcpy.Describe(input_Feature).dataType
    input_Fields = parameter1
    if dataType == 'FeatureLayer':
        arcpy.AddMessage('Input Feature: {0}'.format(input_Feature.name))
    arcpy.AddMessage('Fields to clean: {0}'.format(input_Fields))

    #Convert Params to Field Names for Cursor
    fieldNames =  input_Fields.split(";")

    #Identify workspace
    if dataType == 'FeatureLayer':
        workspace = input_Feature.connectionProperties["connection_info"]["database"]
        arcpy.AddMessage('Workspace: {0}'.format(workspace))

    with arcpy.da.UpdateCursor(input_Feature, fieldNames) as cursor:
        for row in cursor:
            attribute_list = list(row)
            new_l = [None if not item or item.isspace() else re.sub('\s{2,}', ' ', item).strip() for item in attribute_list]
            row = tuple(new_l)

if __name__ == '__main__':
    # ScriptTool parameters
    parameter0 = arcpy.GetParameter(0)
    parameter1 = arcpy.GetParameterAsText(1)

    ScriptTool(parameter0, parameter1)
  • If you were able to defeat the locking, you'd only corrupt the dataset. Instead, try to work with locking, and detect a lack of a write lock at the start of the script
    – Vince
    Commented Apr 25, 2021 at 14:17
  • Hey John, were you ever able to figure this out? I'm having a similar problem with my python toolbox, and checking 'arcpy.TestSchemaLock' doesn't help me - it returns 'True' whether the attribute table is open or not. And if the attribute table is open, I get "RuntimeError: Cannot acquire a lock."
    – Brennan
    Commented Feb 24, 2022 at 21:57
  • I can't find a way to detect this either. I tried running an update cursor in a try: but it won't detect a lock until something is updated.
    – John M
    Commented Aug 5, 2022 at 0:54


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.