Abaixo está o código que estou usando para replicar o botão "tabelas relacionadas" no ArcMap. No ArcMap, esse botão seleciona recursos em uma classe ou tabela de recursos com base na seleção de recursos em outra classe ou tabela de recursos relacionados.
No ArcMap, posso usar esse botão para "empurrar" minha seleção para a tabela relacionada em questão de segundos. Não consegui encontrar nada embutido no arcpy que replica o botão, então usei alguns loops aninhados para fazer a mesma tarefa.
O código abaixo percorre uma tabela de "tratamentos". Para cada tratamento, ele percorre uma lista de "árvores". Quando uma correspondência é encontrada entre os campos de tratamento e árvores de ID, ocorre uma seleção na camada de árvore. Depois que uma correspondência é encontrada para um tratamento, o código não continua a procurar na camada da árvore por correspondências adicionais. Volta para a tabela de tratamento, seleciona o próximo tratamento e pesquisa novamente na classe de recurso de árvore.
O código em si funciona bem, mas é extremamente lento. A "tabela de tratamento" neste caso possui 16.000 registros. A classe de recurso "árvore" possui 60.000 registros.
Existe outra maneira mais eficiente de recriar o que a ESRI está fazendo quando empurra a seleção de uma tabela para outra? Devo estar criando um índice para as tabelas? NOTA: Esses dados são armazenados em uma SDE.
# Create search cursor to loop through the treatments
treatments = arcpy.SearchCursor(treatment_tv)
treatment_field = "Facility_ID"
for treatment in treatments:
#Get ID of treatment
treatment_ID = treatment.getValue(treatment_field)
# Create search cursor for looping through the trees
trees = arcpy.SearchCursor(tree_fl)
tree_field = "FACILITYID"
for tree in trees:
# Get FID of tree
tree_FID = tree.getValue(tree_field)
if tree_FID == treatment_FID:
query = "FACILITYID = " + str(tree_FID)
arcpy.SelectLayerByAttribute_management(tree_fl, "REMOVE_FROM_SELECTION", query)
break
fonte
Respostas:
Primeiro, sim, você definitivamente desejará garantir que seus campos de chave primária e externa sejam indexados nas duas tabelas. Isso permite que o DBMS planeje e execute consultas nesses campos com muito mais eficiência.
Em segundo lugar, você está chamando
SelectLayerByAttribute_management
um loop aninhado (uma vez por árvore por tratamento). Isso é altamente ineficiente, por várias razões:Em vez disso, refatorar seu código para que você chame
SelectLayerByAttribute_management
apenas uma vez com uma cláusula where construída para selecionar todos os registros relacionados.Tomando emprestada uma função de outra resposta para a lógica de construção em que estamos, eu imaginaria que seria algo parecido com isto:
Você poderia chamar assim:
selectRelatedRecords(treatment_tv, tree_fl, "Facility_ID", "FACILITYID")
Notas:
Isso usa um
arcpy.da.SearchCursor
, disponível apenas na 10.1. Como o @PolyGeo mencionou, esses cursores são muito mais rápidos que seus antecessores (arcpy.SearchCursor
). Poderia ser facilmente modificado para usar o antigo SearchCursor:Se o seu geodatabase da SDE estiver no Oracle, saiba que a
IN
declaração usada na função da resposta vinculada é limitada a 1000 elementos. Uma solução possível é descrita nesta resposta , mas você teria que modificar a função para dividi-la em váriasIN
instruções de 1000 comprimentos , em vez de uma.fonte
A solução acima funciona muito bem para mim e foi muito rápida. Usando o código acima e o código referenciado do outro post, é assim que eu o construí:
fonte