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.