Blocco file ArcGIS Python SearchCursor?


11

Ho uno script che ottiene un valore dal campo di uno shapefile per tornare all'utente.

Sembra che solo quando arcpy.SearchCursor si chiama ArcMap 10.0 blocca il file e non viene rimosso al termine dell'esecuzione dello script. Per togliere il blocco devo chiudere ArcMap. Nello script elimino l'oggetto SearchCursor dopo averlo usato e l'oggetto riga.

Il modo in cui lo script funziona è che tenta di eliminare la cartella dell'area di lavoro nelle esecuzioni successive ma non è possibile a causa del blocco ... fino a quando, naturalmente, non chiudo ArcMap.

C'è qualche consiglio su come far sparire questo lucchetto?

Risposte:


4

il problema è stato risolto dopo essere passato da:

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

per

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

3

Vedere Impossibile eliminare il blocco sul file geodatabase e sulla classe di funzionalità creati nello script Python . Sembra lo stesso problema. L'ho già risolto eliminando esplicitamente la classe di funzionalità. Non sono sicuro che funzionerà in tutti i casi.

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)

Anche forzare una garbage collection potrebbe funzionare, ma il mio sospetto è che ciò abbia a che fare con il funzionamento interno di arcpy o ArcMap.

import gc
gc.collect()

L'ho modificato, poiché il riferimento di riga deve essere rimosso dopo ogni iterazione del cursore, altrimenti la chiamata all'esterno del loop è superflua. Questo è anche uno che ho votato come l'unico modo per aggirare lo stesso problema quando l'ho avuto.
Peloso

@Hairy OK, ma penso che sia un punto muto. Python decrementa i riferimenti all'oggetto riga precedente su ogni iterazione quando un nuovo oggetto riga viene assegnato alla variabile riga . row = Nonedopo il loop semplicemente pulisce l'ultima assegnazione di riga. Spostarlo all'interno del loop è una duplicazione degli sforzi. In ogni caso, il garbage collector dovrebbe deallocare la memoria a meno che arcpy o ArcMap mantengano internamente un riferimento agli oggetti riga.
tharen,

va bene accettare di non essere d'accordo, o essendo un punto controverso. So che la raccolta dei rifiuti in arcpy è difettosa ed è in realtà molto più veloce se la spegni. Per quanto riguarda la riga impostata su nulla nella riga, so che funziona meglio in questo modo. Alcuni direbbero che impostare nulla su nessuno è superfluo, ma non lo è. Prova a disattivare la raccolta dei rifiuti all'inizio dello script e misura le differenze di tempo. Uso anche del row, non row = none, ma questa è un'altra dicussione: prova a import gc gc.disable ()
Peloso,

@Peloso, non mi era mai venuto in mente di disabilitare il gc. Lo proverò.
tharen,

Questo non funziona per me perché ho bisogno della classe di funzionalità. Inoltre in seguito ottengo un UpdateCursor su un'altra classe di funzionalità e anche questo viene bloccato. Ho finito per usare specchi e giochi di prestigio per arrivare dove dovevo essere. Non sono sicuro di quanto durerà. Grazie.
Justin

1

Devi eseguire il tuo script ArcPy da ArcMap? A meno che non faccia parte di un'interfaccia o di una casella degli strumenti che hai creato, puoi eseguirlo al di fuori di ArcMap da una console Python, IDLE o Eclipse ecc. (A condizione che tu abbia una licenza appropriata sulla macchina su cui è in esecuzione). In questo caso, puoi scrivere un piccolo codice Python per generare lo script ArcPy come sottoprocesso e il blocco dovrebbe essere rilasciato alla chiusura del sottoprocesso.

Le serrature ArcGIS sono un dolore. Ho avuto situazioni in cui una serratura persiste anche dopo aver spento la macchina, il che è un dolore monumentale (di solito se Arc si è schiantato prima che possa riordinare le serrature). Come ultima risorsa, in questo caso, utilizzare Esplora risorse per trovare il file .LOCK ed eliminarlo manualmente. Questo non funzionerà se vi si accede da ArcMap o da un processo Python, quindi è relativamente sicuro ... ma questa è davvero una carta Get-Out-of-Jail e non una buona pratica :)


1

Se stai eliminando correttamente sia gli oggetti riga che cursore (ad es. del row, rows) E il blocco rimane, è probabile perché ArcMap stesso, non arcpy, lo sta ancora facendo riferimento.

Lo shapefile è referenziato da un layer nel sommario o è aggiunto al sommario dallo strumento di script?

In quest'ultimo caso, potresti provare a disabilitare "Aggiungi risultati delle operazioni di geoprocessing alla visualizzazione" in Geoprocessing-> Opzioni di geoprocessing in ArcMap.

Un ulteriore suggerimento: se lo stai facendo come un set di dati temporaneo / intermedio e il numero di funzionalità non è troppo grande, prova a utilizzare l'area di in_memorylavoro anziché un file di forma per aggirare completamente il problema di blocco e ottenere anche un buon potenziale aumento delle prestazioni .

Assicurati di eliminare l'area di lavoro in_memory o i set di dati specifici che crei lì usando Elimina (Gestione dati) prima di uscire dallo script, altrimenti continuerà a risiedere in memoria fino alla chiusura dell'applicazione.

Infine, vorrei anche notare che il comportamento di blocco dello shapefile è cambiato in 10.0 per diventare più rigoroso non rimuovendo i file di blocco quando si rimuove un layer dal sommario. Vedi anche questo articolo e questa domanda correlata .


È sicuramente ArcMap. Penso che chiamare un cursore uccida il precedente blocco dei cursori. Chiamo un SearchCursor su un fc ... quindi un UpdateCursor su un altro fc e il blocco precedente scompare. Potrei chiamare un terzo cursore fittizio su un file che non dovrà essere cancellato solo per gestire il blocco che uccide lo stile della scatola nera. Grazie.
Justin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.