Verrouillage du fichier ArcGIS Python SearchCursor?


11

J'ai un script qui obtient une valeur du champ d'un fichier de formes à retourner à l'utilisateur.

Il semble que ce n'est que lorsque l'arcpy.SearchCursor est appelé ArcMap 10.0 verrouille le fichier et qu'il n'est pas supprimé une fois le script terminé. Pour désactiver le verrouillage, je dois fermer ArcMap. Dans le script, je supprime l'objet SearchCursor après l'avoir utilisé ainsi que l'objet ligne.

La façon dont le script fonctionne est qu'il essaie de supprimer le dossier de l'espace de travail lors des exécutions suivantes mais ne peut pas à cause du verrou ... jusqu'à ce que je ferme ArcMap.

Y a-t-il des conseils pour faire disparaître cette serrure?

Réponses:


4

le problème a été résolu après être passé de:

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

à

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

3

Voir Impossible de supprimer le verrouillage de la géodatabase fichier et de la classe d'entités créés dans le script Python . Cela ressemble au même problème. Je l'ai contourné auparavant en supprimant explicitement la classe d'entités. Je ne sais pas si cela fonctionnera dans tous les cas.

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)

Forcer une récupération de place peut également fonctionner, mais mon intuition est que cela a quelque chose à voir avec le fonctionnement interne d'arcpy ou d'ArcMap.

import gc
gc.collect()

J'ai modifié cela, car la référence de ligne doit être supprimée après chaque itération du curseur, sinon l'appel en dehors de la boucle est superflu. C'est aussi celui que j'ai voté car c'est le seul moyen de contourner le même problème quand je l'ai eu.
Hairy

@ Hairy OK, mais je pense que c'est un point muet. Python décrémente les références à l' objet de ligne précédent à chaque itération lorsqu'un nouvel objet de ligne est affecté à la variable de ligne . row = Noneaprès la boucle nettoie simplement la dernière affectation de ligne. Le déplacer dans la boucle est une duplication d'efforts. Dans tous les cas, le garbage collector doit désallouer la mémoire, sauf si arcpy ou ArcMap ne conserve pas de manière interne une référence aux objets de ligne.
tharen

c'est ok d'accepter d'être en désaccord, ou c'est un point discutable. Je sais que la collecte des ordures dans arcpy est défectueuse, et est en fait beaucoup plus rapide si vous la désactivez. Quant à la ligne étant définie sur rien dans la ligne, je sais que cela fonctionne mieux de cette façon. Certains diraient que rien ne vaut rien, mais ce n'est pas le cas. Essayez de désactiver votre garbage collection au début de votre script et de mesurer les différences de temps. J'utilise aussi del row, pas row = none, mais c'est une autre discussion: essayez d'importer gc gc.disable ()
Hairy

@Poisson, il ne m'était pas venu à l'esprit de désactiver le gc. Je vais essayer.
tharen

Cela ne fonctionne pas pour moi car j'ai besoin de la classe d'entités. De plus, je reçois plus tard un UpdateCursor sur une autre classe d'entités et cela se verrouille également. J'ai fini par utiliser des miroirs et un tour de main pour arriver là où je devais être. Je ne sais pas combien de temps cela durera. Merci.
Justin

1

Avez-vous besoin d'exécuter votre script ArcPy depuis ArcMap? À moins qu'il ne fasse partie d'une interface ou d'une boîte à outils que vous avez créée, vous pouvez l'exécuter en dehors d'ArcMap à partir d'une console Python, IDLE ou Eclipse, etc. (tant que vous disposez d'une licence appropriée sur la machine sur laquelle il fonctionne). Si tel est le cas, vous pouvez écrire un petit code Python pour générer votre script ArcPy en tant que sous-processus et le verrou doit être libéré à la fermeture du sous-processus.

Les verrous ArcGIS sont pénibles. J'ai eu des situations où une serrure persiste même après l'arrêt de la machine, ce qui est une douleur monumentale (généralement si Arc s'est écrasé avant de pouvoir ranger les serrures). En dernier recours, si cela se produit, utilisez l'Explorateur Windows pour rechercher le fichier .LOCK et supprimez-le manuellement. Cela ne fonctionnera pas si ArcMap ou un processus Python y accède, donc c'est relativement sûr ... mais c'est vraiment une carte de sortie de prison et ce n'est pas une bonne pratique :)


1

Si vous supprimez correctement les objets ligne et curseur (par exemple del row, rows) et que le verrou reste, c'est probablement parce qu'ArcMap lui-même, et non arcpy, le fait toujours référence.

Le fichier de formes est-il référencé par une couche dans la table des matières, ou est-il ajouté à la table des matières par votre outil de script?

Dans ce dernier cas, vous pouvez essayer de désactiver "Ajouter les résultats des opérations de géotraitement à l'affichage" sous Géotraitement-> Options de géotraitement dans ArcMap.

Une suggestion supplémentaire: si vous faites cela en tant que jeu de données temporaire / intermédiaire et que le nombre d'entités n'est pas trop important, essayez d'utiliser l' in_memoryespace de travail au lieu d'un fichier de formes pour contourner entièrement le problème de verrouillage et obtenir également une augmentation potentielle des performances. .

Assurez-vous simplement de supprimer l'espace de travail in_memory ou les ensembles de données spécifiques que vous y créez à l'aide de Delete (Data Management) avant de quitter le script, sinon il continuera à résider en mémoire jusqu'à la fermeture de l'application.

Enfin, je voudrais également noter que le comportement de verrouillage des fichiers de formes a changé dans 10.0 pour devenir plus strict en ne supprimant pas les fichiers de verrouillage lorsque vous supprimez un calque de la table des matières. Voir également cet article et cette question connexe .


Il s'agit bien d'ArcMap. Je pense qu'appeler un curseur tue le verrou des curseurs précédent. J'appelle un SearchCursor sur un fc .. puis un UpdateCursor sur un autre fc et le verrou précédent disparaît. Je peux appeler un curseur factice tridimensionnel sur un fichier qui n'aura pas besoin d'être supprimé juste pour gérer le style de boîte noire qui tue le verrou. Merci.
Justin
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.