Bloqueio de arquivos do ArcGIS Python SearchCursor?

11

Eu tenho um script que obtém um valor do campo de um shapefile para retornar ao usuário.

Parece que somente quando o arcpy.SearchCursor é chamado ArcMap 10.0, bloqueia o arquivo e não é removido após a execução do script. Para desativar o bloqueio, preciso fechar o ArcMap. No script, excluo o objeto SearchCursor depois de usá-lo, bem como o objeto de linha.

A maneira como o script funciona é que ele tenta excluir a pasta da área de trabalho nas execuções subseqüentes, mas não pode por causa do bloqueio ... até, é claro, que eu feche o ArcMap.

Existe algum conselho para que essa trava desapareça?

Justin
fonte

Respostas:

4

o problema foi resolvido após passar de:

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

para

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

Consulte Não é possível se livrar do bloqueio no geodatabase de arquivo e na classe de recurso criada no script Python . Parece o mesmo problema. Eu já havia contornado isso excluindo explicitamente a classe de recurso. Não tenho certeza se isso funcionará em todos os 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)

Forçar uma coleta de lixo também pode funcionar, mas meu palpite é que isso tem algo a ver com o funcionamento interno do arcpy ou ArcMap.

import gc
gc.collect()
tharen
fonte
Eu editei isso, pois a referência da linha deve ser removida após cada iteração do cursor, caso contrário, a chamada fora do loop é supérflua. Essa também foi a que eu votei, pois é a única maneira de resolver o mesmo problema quando o fiz.
Peludo
@ Hairy OK, mas acho que é um ponto mudo. O Python diminui as referências ao objeto de linha anterior em cada iteração quando um novo objeto de linha é atribuído à variável de linha . row = Noneapós o loop simplesmente limpa a última atribuição de linha. Movê-lo para dentro do loop é uma duplicação de esforços. De qualquer forma, o coletor de lixo deve desalocar a memória, a menos que o arcpy ou o ArcMap mantenha uma referência interna aos objetos de linha.
tharen
não há problema em concordar em discordar, ou é um ponto discutível. Eu sei que a coleta de lixo no arcpy é falha e, na verdade, é muito mais rápida se você a desativar. Quanto à linha ser definida como nada na linha, eu sei que funciona melhor assim. Alguns diriam que definir algo como nada é supérfluo, mas não é. Tente desativar sua coleta de lixo no início do seu script e meça as diferenças de horário. Eu também uso del fila, não remar = nenhum, mas isso é outra dicussion: tentativa de importação gc gc.disable ()
Hairy
@ Hairy, não me ocorreu desativar o gc. Vou dar uma chance.
Tharen
Isso não funciona para mim porque preciso da classe de recurso. Além disso, mais tarde recebo um UpdateCursor em outra classe de recurso e isso fica bloqueado também. Acabei usando espelhos e truques para chegar onde eu precisava estar. Não tenho certeza de quanto tempo ele vai aguentar. Obrigado.
Justin
1

Você precisa executar seu script ArcPy de dentro do ArcMap? A menos que faça parte de uma interface ou caixa de ferramentas que você construiu, você pode executá-lo fora do ArcMap a partir de um console Python, IDLE ou Eclipse etc. (desde que você tenha uma licença apropriada na máquina em que está executando). Se for esse o caso, você pode escrever um pequeno código Python para gerar seu script ArcPy como um subprocesso, e o bloqueio deverá ser liberado quando o subprocesso for fechado.

Os bloqueios do ArcGIS são uma dor. Eu tive situações em que uma trava persiste mesmo depois de desligar a máquina, o que é uma dor monumental (geralmente se o Arc travou antes de poder arrumar as travas). Como último recurso, se isso acontecer, use o Windows Explorer para encontrar o arquivo .LOCK e exclua-o manualmente. Isso não funcionará se estiver sendo acessado pelo ArcMap ou por um processo Python, por isso é relativamente seguro ... mas essa é realmente uma placa Get-Out-of-Jail e não é uma boa prática :)

MappaGnosis
fonte
1

Se você estiver excluindo corretamente os objetos de linha e cursor (por exemplo del row, rows) e o bloqueio permanecer, é provável que o próprio ArcMap, não o arcpy, ainda esteja fazendo referência a ele.

O shapefile é referenciado por uma camada no índice ou é adicionado ao sumário pela sua ferramenta de script?

Neste último caso, você pode tentar desativar "Adicionar resultados de operações de geoprocessamento à tela" em Geoprocessamento-> Opções de geoprocessamento no ArcMap.

Uma sugestão adicional: se você estiver fazendo isso como um conjunto de dados temporário / intermediário, e o número de recursos não for muito grande, tente usar a área de in_memorytrabalho em vez de um shapefile para solucionar completamente o problema de bloqueio e obter um bom aumento potencial de desempenho também .

Apenas certifique-se de excluir o espaço de trabalho in_memory ou os conjuntos de dados específicos criados por ele usando Excluir (Gerenciamento de Dados) antes de sair do script, caso contrário, ele continuará residindo na memória até que o aplicativo seja fechado.

Por fim, também observaria que o comportamento de bloqueio do shapefile mudou na 10.0 para se tornar mais rigoroso, não removendo os arquivos de bloqueio quando você remove uma camada do sumário. Consulte também este artigo e esta questão relacionada .

blah238
fonte
Definitivamente é o ArcMap. Eu acho que chamar um cursor mata o bloqueio de cursores anterior. Eu chamo um SearchCursor em um fc ... depois um UpdateCursor em outro fc e o bloqueio anterior desaparece. Posso chamar um cursor fictício thrid em um arquivo que não precisará ser excluído apenas para lidar com o estilo de caixa preta de bloqueio de bloqueio. Obrigado.
Justin