1

I have a script which removes a layer from the MXD, and then re-creates the feature from scratch in a GDB and adds the layer back in.

If I remove the layer manually before running the script, it runs fine. But if I remove the layer in the script, the script later fails when trying to re-create the GDB due to a lock. This is resolved by reloading the MXD.

Traceback (most recent call last): File "D:\RouteSmart_Work\Tools and Utilities\Python - Street Assignment Visualiser\StreetAssignment.py", line 60, in arcpy.CreateFileGDB_management(outputFolder, "StreetAssignments.gdb") File "c:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\management.py", line 16594, in CreateFileGDB raise e ExecuteError: ERROR 999999: Error executing function. Failed to execute (CreateFileGDB).

I've tried implementing arcpy.Compact_management (credit to StacyR from another and gc.collect() but these still don't seem to clear the lock. Could anyone advise if I'm missing anything? The script is meant to be run frequently, without the need to remove the layer each time.

def clearWSLocks(inputWS):
  '''Attempts to clear locks on a workspace, returns stupid message.'''
  if all([arcpy.Exists(inputWS), arcpy.Compact_management(inputWS), arcpy.Exists(inputWS)]):
    return 'Workspace (%s) clear to continue...' % inputWS
  else:
    return '!!!!!!!! ERROR WITH WORKSPACE %s !!!!!!!!' % inputWS

arcpy.env.overwriteOutput = True

servLoc_layer = arcpy.GetParameterAsText(0)
streets_layer = arcpy.GetParameterAsText(1)
outputFolder = arcpy.GetParameterAsText(2)

# Remove the layer if it's already in the data frame
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]
if arcpy.Exists("FC"):  # Use name rather than layer object in case name doesn't exist
    lyr = arcpy.mapping.Layer("FC")  # Create layer object in order to remove it
    arcpy.mapping.RemoveLayer(df, lyr)
    arcpy.RefreshActiveView()
    del lyr, df, mxd

outGDB = os.path.join(outputFolder, "GDB.gdb") # Geodatabase

xyLineOutput = os.path.join(outGDB,"FC")
if arcpy.Exists(xyLineOutput):
    arcpy.Delete_management(xyLineOutput)

gc.collect()

if arcpy.Exists(outGDB):
    arcpy.AddMessage(clearWSLocks(outGDB))
    arcpy.Delete_management(outGDB)
arcpy.CreateFileGDB_management(outputFolder, "GDB.gdb")

EDIT:

In this instance I've instructed the user to remove the layer manually before running the script, to keep the one GDB as the workspace. It's only a small geoprocessing task, so the data management will be simple. I will bear Vince's comment in mind for the future.

closed as off-topic by PolyGeo Feb 1 '17 at 1:16

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This problem cannot or can no longer be reproduced. Changes to the system or to the asker's circumstances may have rendered the question obsolete, or the question does not include a procedure to enable potential answerers to reproduce the same symptoms. Such questions are off-topic as they are unlikely to help future readers, but editing them to include more details can lead to re-opening." – PolyGeo
If this question can be reworded to fit the rules in the help center, please edit the question.

  • There are several different kinds of locks. Is your code sample missing an arcpy.env.workspace = ...? – Vince Jan 30 '17 at 14:35
  • You need to delete the gdb or just the feature class? Reason I ask is maybe you are getting that error because you have other locked layers in the gdb. – artwork21 Jan 30 '17 at 14:36
  • 1
    I suspect you have uncollected references within the Python framework which are preserving locks. What you are trying to do is so fraught with risk that I would never attempt it. Instead I would create a differently named FGDB in the same directory or an identically named FGDB in a different directory (for the record, I would never name a file geodatabase "GDB"). – Vince Jan 30 '17 at 14:53
  • 2
    I can't tell what your purpose is in this exercise. I've been writing import and export utilities for nearly thirty years, and I've never needed to replace the existing container to which multiple references already exist to recreate the data. The usual pattern is to truncate existing data and append in situ. If the schema changes, then drop, recreate as an empty table, and append. If I need to recreate the container, it's done in a different parent directory (usually with a release-based name). – Vince Jan 30 '17 at 15:30
  • 1
    @Mike please edit your question to include new information rather than commenting. Comments are for potential answerers to request clarification or additional info, your response should be as edits to the question. – Midavalo Jan 30 '17 at 15:57