Select to view content in your preferred language

Randomly occuring python errors in script

2344
1
09-06-2013 07:34 AM
AndrewBlakey1
Emerging Contributor
I've got a long script that performs a bunch of different geoprocessing tasks. It creates a File GDB, creates empty feature classes and builds data, often with cursors.  1/2 the time I run the script, it always runs into errors about schema locks or simply fails to run a function that worked previously.

While my full code is longer and I don't want to share it all, this subsection will throw errors randomly. The latest is:

Traceback (most recent call last):
  File "C:\Users\ablakey\Documents\Projects\RapidQuotes\rq.py", line 66, in <module>
    arcpy.CalculatePolygonMainAngle_cartography("waterbodyBound", "angle","GEOGRAPHIC")
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\cartography.py", line 350, in CalculatePolygonMainAngle
    raise e
arcgisscripting.ExecuteError: ERROR 000582: Error occurred during execution.


It's as if the code is stumbling over itself when it comes to locks. Is there something I'm missing to create an FC and then have it ready and unlocked when the next function tries to edit it?

# 0. Delete Previous Data
if arcpy.Exists("c:/Users/ablakey/Documents/Projects/RapidQuotes/geodata/rq.gdb"):  
    arcpy.Delete_management("c:/Users/ablakey/Documents/Projects/RapidQuotes/geodata/rq.gdb/")
arcpy.CreateFileGDB_management("c:/Users/ablakey/Documents/Projects/RapidQuotes/geodata", "rq.gdb")

# 0.1. Create Empty FCs
arcpy.CreateFeatureclass_management(ws,"pathLines", "POLYLINE", spatial_reference = spatial_reference)


# 1. Buffer Waterbody
arcpy.Buffer_analysis(waterbodyPoly,"waterbodyBuffer",0 - shorelineBuffer)

# 2. Get Bounding Box
arcpy.MinimumBoundingGeometry_management("waterbodyBuffer","waterbodyBound","RECTANGLE_BY_WIDTH")

# 3. Add "angle" Field
arcpy.AddField_management("waterbodyBound","angle","DOUBLE")

# 4. Calculate Angle
arcpy.CalculatePolygonMainAngle_cartography("waterbodyBound", "angle","GEOGRAPHIC")
Tags (2)
1 Reply
StacyRendall1
Frequent Contributor
For a while I had a spate of problems similar to yours, but it seems to have cleared itself up. Not sure if I am just writing less lock-prone code, or if an ArcGIS patch along the way fixed something up. Here are two things which might help you:

  • Using Exists, Compact, Exists on the GDB in question. This seems to force a refresh and can sometimes clear out the locks. To do it in only one line of code:

  • [INDENT]
    #input GDB is testWS
    [arcpy.Exists(testWS), arcpy.Compact(testWS), arcpy.Exists(testWS)]
    [/INDENT]
  • I wrote a function that will kill any process, except for the running process, that might have the workspace open. If it is this process that has the workspace open it will repeat the above step indefinitely until the lock disappears. I mostly used this when running scripts that use multiple CPUs at the same time. It can also close ArcMap or Catalog if you accidentally had them open using your workspace. It requires that you import the os library (part of Python), and download, install and import the Psutil library. It is definitely not fool-proof and can raise exceptions if a process is found that has the workspace open but that process closes its handle before the code gets to doing it. To use, add this to the top of your code:

  • [INDENT]
    import os
    import psutil
    
    def clearWSLocks(inputWS):
     '''Attempts to clear ArcGIS/Arcpy locks on a workspace.
     Two methods:
      1: if ANOTHER process (i.e. ArcCatalog) has the workspace open, that process is terminated
      2: if THIS process has the workspace open, it attempts to clear locks using arcpy.Exists, arcpy.Compact and arcpy.Exists in sequence
    
     Required imports: os, psutil
     '''
    
     # get process ID for this process (treated differently)
     thisPID = os.getpid()
    
     # normalise path
     _inputWS = os.path.normpath(inputWS)
    
     # get list of currently running Arc/Python processes
     p_List = []
     ps = psutil.process_iter()
     for p in ps:
      if ('Arc' in p.name) or ('python' in p.name):
       p_List.append(p.pid)
    
     # iterate through processes
     for pid in p_List:
      try:
       p = psutil.Process(pid)
      except: # psutil NoSuchProcess...
       p = False
    
      # if any have the workspace open
      if p and any(_inputWS in pth for pth in [fl.path for fl in p.get_open_files()]):
       print '      !!! Workspace open: %s' % _inputWS
    
       # terminate if it is another process
       if pid != thisPID:
        print '      !!! Terminating process: %s' % p.name
        p.terminate()
       else:
        print '      !!! This process has workspace open...'
    
     # if this process has workspace open, keep trying while it is open...
     while any(_inputWS in pth for pth in [fl.path for fl in psutil.Process(thisPID).get_open_files()]):
      print '    !!! Trying Exists, Compact, Exists to clear locks: returned %s' % all([arcpy.Exists(_inputWS), arcpy.Compact_management(_inputWS), arcpy.Exists(_inputWS)])
    
     return True

    then use a function call to try and clear the locks, like so:
    clearWSLocks(testWS)

    If it often throws exceptions, you could do this (but it may then not clear the locks...):
    try:
        clearWSLocks(testWS)
    except:
        pass
    [/INDENT]

Let me know if either of these help! I haven't used the function for a while, and had to adapt it a bit for posting, so there may be errors in it... You can use trial and error to work out where you need to use these within the code.
0 Kudos