A continuación se muestra el código que estoy usando para replicar el botón "tablas relacionadas" en ArcMap. En ArcMap, ese botón selecciona entidades en una clase de entidad o tabla en función de la selección de entidades en otra clase de entidad o tabla relacionada.
En ArcMap puedo usar ese botón para "empujar" mi selección a la tabla relacionada en cuestión de segundos. No pude encontrar nada integrado en arcpy que replicara el botón, así que usé algunos bucles anidados para hacer la misma tarea.
El siguiente código recorre una tabla de "tratamientos". Para cada tratamiento, recorre una lista de "árboles". Cuando se encuentra una coincidencia entre los campos ID de tratamiento y los árboles, se produce una selección en la capa del árbol. Una vez que se encuentra una coincidencia para un tratamiento, el código no continúa buscando coincidencias adicionales en la capa del árbol. Vuelve a la tabla de tratamiento, selecciona el siguiente tratamiento y vuelve a buscar en la clase de entidad de árbol.
El código en sí funciona bien, pero es extremadamente lento. La "tabla de tratamiento" en este caso tiene 16,000 registros. La clase de entidad "árbol" tiene 60,000 registros.
¿Hay otra manera más eficiente de recrear lo que está haciendo ESRI cuando empuja la selección de una tabla a otra? ¿Debo estar creando un índice para las tablas? NOTA: estos datos se almacenan en un 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
Respuestas:
En primer lugar, sí, definitivamente querrá asegurarse de que sus campos de clave primaria y externa estén indexados en ambas tablas. Esto permite que el DBMS planifique y ejecute consultas en estos campos de manera mucho más eficiente.
En segundo lugar, está llamando
SelectLayerByAttribute_management
en un ciclo cerrado y anidado (una vez por árbol por tratamiento). Esto es altamente ineficiente, por varias razones:En su lugar, refactorice su código para que llame
SelectLayerByAttribute_management
solo una vez con una cláusula where construida para seleccionar todos los registros relacionados.Tomando prestada una función de otra respuesta para la lógica de construcción whereclause, me imagino que se vería así:
Podrías llamarlo así:
selectRelatedRecords(treatment_tv, tree_fl, "Facility_ID", "FACILITYID")
Notas:
Esto utiliza un
arcpy.da.SearchCursor
, solo disponible en 10.1. Como @PolyGeo mencionó, estos cursores son mucho más rápidos que sus predecesores (arcpy.SearchCursor
). Sin embargo, podría modificarse fácilmente para usar el antiguo SearchCursor:Si su geodatabase SDE está en Oracle, tenga en cuenta que la
IN
declaración utilizada en la función de la respuesta vinculada está limitada a 1000 elementos. En esta respuesta se describe una posible solución , pero tendría que modificar la función para dividirla en variasIN
declaraciones de 1000 en lugar de una.fuente
La solución anterior funciona muy bien para mí y fue muy rápida. Utilizando el código anterior y el código referenciado de la otra publicación, así es como lo construí:
fuente