Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have a script that gets a value from a shapefile's field to return to the user.

It seems that only when the arcpy.SearchCursor is called ArcMap locks the file and it doesn't get removed after the script is finished running. To get the lock off I have to close ArcMap. In the script I delete the SearchCursor object after using it as well as the row object.

The way I have the script working is that it tries to delete the workspace folder on subsequent runs but can't because of the lock...until of course I close ArcMap.

Is there any advice on getting this lock to go away? This seems to be a new occurence for me. Thanks.

share|improve this question

4 Answers 4

See this post. It looks like the same issue. I have gotten around it before by explicitly deleting the feature class. I'm not sure if this will work in all cases.

import arcpy

fcPath = 'c:/temp/features.shp'
idFld = 'OBJECTID'
cur = arcpy.SearchCursor(fcPath)
for row in cur:
    id = row.getValue(idFld)
    row = None
cur = None
r = arcpy.Delete_management(fcPath)

print r.getOutput(0)

Forcing a garbage collection may work as well, but my hunch is that this has something to do with the internal workings of arcpy or ArcMap.

import gc
gc.collect()
share|improve this answer
    
I edited this, as the row reference should be removed after each iteration of the cursor, otherwise the call outside the loop is superfluous. This is also one I voted up as its the only way I could get around the same issue when I had it. –  Hairy Jan 28 '12 at 21:21
    
@Hairy OK, but I think it's a mute point. Python decrements the references to the previous row object on each iteration when a new row object is assigned to the row variable. row = None after the loop simply cleans up the last row assignment. Moving it inside the loop is duplication of effort. In any case, the garbage collector should deallocate the memory unless arcpy or ArcMap inerternally maintains a reference to the row objects. –  tharen Jan 29 '12 at 7:48
    
its ok to agree to disagree, or it being a moot point. I know that garbage collection in arcpy is flawed, and is actually a lot quicker if you turn it off. As for the row being set to nothing in the row, I know it works better that way. Some would say setting anything to none is superfluous, but it isn't. Have a go at turning your garbage collection off at the start of your script and measure the time differences. I also use del row, not row = none, but that's another dicussion: try import gc gc.disable() –  Hairy Jan 29 '12 at 8:03
    
@Hairy, It hadn't occurred to me to disable the gc. I'll give it a try. –  tharen Jan 29 '12 at 9:11
    
This doesn't work for me because I need the feature class. Also I later get a UpdateCursor on another feature class and this get locked also. I ended up using mirrors and sleight of hand to get where I need to be. Not sure how long it will hold up. Thanks. –  Justin Jan 30 '12 at 16:32

If you are properly deleting both the row and cursor objects (e.g. del row, rows) and the lock remains, it's likely because ArcMap itself, not arcpy, is still referencing it.

Is the shapefile referenced by a layer in the table of contents, or is it added to the TOC by your script tool?

If the latter, you might try disabling "Add results of geoprocessing operations to the display" under Geoprocessing->Geoprocessing Options in ArcMap.

An additional suggestion: If you are doing this as a temporary/intermediate dataset, and the number of features is not too large, try using the in_memory workspace instead of a shapefile to get around the locking problem entirely and get a nice potential performance increase as well.

Just be sure to delete the in_memory workspace or the specific datasets you create there using Delete (Data Management) before exiting the script, otherwise it will continue to reside in memory until the application closes.

Lastly I would also note that shapefile locking behavior changed in 10.0 to become more strict (read: more of a PITA) by not removing the lock files when you remove a layer from the table of contents. See also this article and this related question.

share|improve this answer
    
It is definitely ArcMap. I think calling an cursor kills the previous cursors lock. I call a SearchCursor on a fc..then an UpdateCursor on another fc and the previous lock goes away. I may call a thrid dummy cursor on a file that will not need to be deleted just to handle the lock killing black box style. Thanks. –  Justin Jan 30 '12 at 16:35

Do you need to run your ArcPy script from inside ArcMap? Unless it's part of an interface or toolbox you've built, you can run it outside ArcMap from a Python console, IDLE, or Eclipse etc (so long as you have an appropriate licence on the machine it's running on). If this is the case you can write a little Python code to spawn your ArcPy script as a subprocess and the lock should be released when the subprocess closes.

ArcGIS locks are a pain. I have had situations where a lock persists even after shutting down the machine, which is a monumental pain (usually if Arc has crashed before it can tidy up the locks). As a last resort, if this happens, use Windows Explorer to find the .LOCK file and delete it manually. This won't work if it is being accessed by ArcMap or a Python process, so it is relatively safe... but this is really a Get-Out-of-Jail card and not good practice :)

share|improve this answer

correction----
the problem was solved after going from:

rows = arcpy.UpdateCursor(fc)   
delete = rows.deleteRow  
for row in rows:  
    delete(row)  
del row  
del rows

to

rows = arcpy.UpdateCursor(fc)
for row in rows:
    rows.deleteRow(row)
del row
del rows
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.