Ниже приведен код, который я использую для репликации кнопки «связанные таблицы» в ArcMap. В ArcMap эта кнопка выбирает объекты в одном классе пространственных объектов или таблице на основе выбора объектов в другом связанном классе пространственных объектов или таблице.
В ArcMap я могу использовать эту кнопку, чтобы «перенести» свой выбор в связанную таблицу за считанные секунды. Я не смог найти ничего встроенного в arcpy, который бы дублировал кнопку, поэтому я использовал несколько вложенных циклов для выполнения той же задачи.
Код ниже просматривает таблицу «процедур». Для каждой процедуры он просматривает список «деревьев». Когда найдено совпадение между полями идентификаторов обработки и деревьями, выбор происходит в слое дерева. После того, как для обработки найдено совпадение, код не продолжает поиск дополнительных совпадений в слое дерева. Он возвращается к таблице процедур, выбирает следующую процедуру и снова просматривает древовидный класс пространственных объектов.
Сам код работает нормально, но мучительно медленно. «Таблица обработки» в этом случае имеет 16 000 записей. Класс объектов «дерево» содержит 60 000 записей.
Есть ли другой более эффективный способ воссоздать то, что делает ESRI, когда он перемещает выбор из одной таблицы в другую? Должен ли я создавать индекс для таблиц? ПРИМЕЧАНИЕ. Эти данные хранятся в 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
Ответы:
Во-первых, да, вы определенно захотите убедиться, что поля первичного и внешнего ключей проиндексированы в обеих таблицах. Это позволяет СУБД гораздо эффективнее планировать и выполнять запросы к этим полям.
Во-вторых, вы вызываете
SelectLayerByAttribute_management
в тесном, вложенном цикле (один раз на дерево за обработку). Это крайне неэффективно по нескольким причинам:Вместо этого
SelectLayerByAttribute_management
выполните рефакторинг вашего кода, чтобы вы вызывали его только один раз с предложением where, созданным для выбора всех связанных записей.Заимствуя функцию из другого ответа для логики построения whereclause, я бы предположил, что это будет выглядеть примерно так:
Вы могли бы назвать это так:
selectRelatedRecords(treatment_tv, tree_fl, "Facility_ID", "FACILITYID")
Примечания:
Это использует
arcpy.da.SearchCursor
, доступно только в 10.1. Как упомянул @PolyGeo, эти курсоры намного быстрее, чем их предшественники (arcpy.SearchCursor
). Это может быть легко изменено, чтобы использовать старый SearchCursor, хотя:Если ваша база геоданных SDE находится в Oracle, имейте в виду, что
IN
оператор, используемый в функции из связанного ответа, ограничен 1000 элементами. В этом ответе описано одно из возможных решений , но вам придется изменить функцию, чтобы разделить ее на несколькоIN
операторов длиной 1000 вместо одного.источник
Вышеупомянутое решение прекрасно работает для меня и было очень быстрым. Используя приведенный выше код и ссылочный код из другого поста, вот как я его построил:
источник