¿Bloqueo del archivo ArcGIS Python SearchCursor?

11

Tengo un script que obtiene un valor del campo de un shapefile para devolverlo al usuario.

Parece que solo cuando arcpy.SearchCursor se llama ArcMap 10.0 bloquea el archivo y no se elimina una vez que el script termina de ejecutarse. Para desactivar el bloqueo, tengo que cerrar ArcMap. En el script, elimino el objeto SearchCursor después de usarlo, así como el objeto de fila.

La forma en que tengo el script funcionando es que intenta eliminar la carpeta del espacio de trabajo en ejecuciones posteriores pero no puede debido al bloqueo ... hasta que, por supuesto, cierro ArcMap.

¿Hay algún consejo para que esta cerradura desaparezca?

Justin
fuente

Respuestas:

4

El problema se resolvió después de pasar de:

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

a

rows = arcpy.UpdateCursor(fc)
for row in rows:
    rows.deleteRow(row)
del row
del rows
b.bacia
fuente
3

Consulte No se puede deshacer el bloqueo en la geodatabase de archivos y la clase de entidad creada en el script de Python . Parece el mismo problema. Lo he solucionado antes eliminando explícitamente la clase de entidad. No estoy seguro de si esto funcionará en todos los casos.

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)

Forzar una recolección de basura también puede funcionar, pero mi presentimiento es que esto tiene algo que ver con el funcionamiento interno de arcpy o ArcMap.

import gc
gc.collect()
tharen
fuente
Edité esto, ya que la referencia de fila debería eliminarse después de cada iteración del cursor, de lo contrario, la llamada fuera del bucle es superflua. También voté por este, ya que es la única forma en que podría solucionar el mismo problema cuando lo tuviera.
Peludo
@Hairy OK, pero creo que es un punto mudo. Python disminuye las referencias al objeto de fila anterior en cada iteración cuando se asigna un nuevo objeto de fila a la variable de fila . row = Nonedespués del ciclo simplemente limpia la última asignación de fila. Moverlo dentro del bucle es una duplicación de esfuerzo. En cualquier caso, el recolector de basura debe desasignar la memoria a menos que arcpy o ArcMap mantengan inercialmente una referencia a los objetos de la fila.
tharen
está bien estar de acuerdo en no estar de acuerdo, o es un punto discutible. Sé que la recolección de basura en arcpy es defectuosa, y en realidad es mucho más rápida si la apagas. En cuanto a la fila que se establece en nada en la fila, sé que funciona mejor de esa manera. Algunos dirían que establecer nada en ninguno es superfluo, pero no lo es. Intente desactivar su recolección de basura al comienzo de su secuencia de comandos y mida las diferencias horarias. También uso del row, no row = none, pero esa es otra discusión: intente importar gc gc.disable ()
Peludo
@Hairy, no se me había ocurrido desactivar el gc. Lo probaré.
tharen
Esto no funciona para mí porque necesito la clase de entidad. Además, luego obtengo un UpdateCursor en otra clase de entidad y esto también se bloquea. Terminé usando espejos y juegos de manos para llegar a donde necesitaba estar. No estoy seguro de cuánto tiempo aguantará. Gracias.
Justin
1

¿Necesita ejecutar su script ArcPy desde ArcMap? A menos que sea parte de una interfaz o caja de herramientas que haya creado, puede ejecutarla fuera de ArcMap desde una consola Python, IDLE o Eclipse, etc. (siempre que tenga una licencia apropiada en la máquina en la que se está ejecutando). Si este es el caso, puede escribir un pequeño código de Python para generar su script ArcPy como un subproceso y el bloqueo debe liberarse cuando se cierre el subproceso.

Las cerraduras ArcGIS son un dolor. He tenido situaciones en las que persiste un bloqueo incluso después de apagar la máquina, lo cual es un dolor monumental (generalmente si Arc se ha bloqueado antes de que pueda arreglar los bloqueos). Como último recurso, si esto sucede, use el Explorador de Windows para buscar el archivo .LOCK y eliminarlo manualmente. Esto no funcionará si ArcMap o un proceso de Python acceden a él, por lo que es relativamente seguro ... pero esta es realmente una tarjeta para salir de la cárcel y no es una buena práctica :)

MappaGnosis
fuente
1

Si está eliminando correctamente los objetos de fila y cursor (p del row, rows. Ej. ) Y el bloqueo permanece, es probable que ArcMap en sí, no arcpy, todavía lo esté haciendo referencia.

¿El archivo de forma hace referencia a una capa en la tabla de contenido, o su herramienta de script lo agrega al TOC?

Si es esto último, puede intentar desactivar "Agregar resultados de operaciones de geoprocesamiento a la pantalla" en Geoprocesamiento-> Opciones de geoprocesamiento en ArcMap.

Una sugerencia adicional: si está haciendo esto como un conjunto de datos temporal / intermedio, y el número de características no es demasiado grande, intente usar el in_memoryespacio de trabajo en lugar de un archivo de forma para solucionar el problema de bloqueo por completo y obtener un buen aumento potencial de rendimiento también .

Solo asegúrese de eliminar el espacio de trabajo in_memory o los conjuntos de datos específicos que cree allí usando Eliminar (Administración de datos) antes de salir del script, de lo contrario, continuará residiendo en la memoria hasta que se cierre la aplicación.

Por último, también señalaría que el comportamiento de bloqueo del archivo de forma cambió en 10.0 para volverse más estricto al no eliminar los archivos de bloqueo cuando elimina una capa de la tabla de contenido. Vea también este artículo y esta pregunta relacionada .

blah238
fuente
Definitivamente es ArcMap. Creo que llamar a un cursor mata el bloqueo de cursores anterior. Llamo a un SearchCursor en un fc ... luego un UpdateCursor en otro fc y el bloqueo anterior desaparece. Puedo llamar a un tercer cursor ficticio en un archivo que no necesitará eliminarse solo para manejar el estilo de caja negra que mata la cerradura. Gracias.
Justin