Poniżej znajduje się kod, którego używam do replikacji przycisku „powiązanych tabel” w ArcMap. W ArcMap ten przycisk wybiera obiekty w jednej klasie obiektów lub tabeli na podstawie wyboru obiektów w innej pokrewnej klasie obiektów lub tabeli.
W ArcMap mogę użyć tego przycisku, aby „wcisnąć” mój wybór do odpowiedniej tabeli w ciągu kilku sekund. Nie mogłem znaleźć niczego wbudowanego w arcpy, które replikuje przycisk, więc użyłem zagnieżdżonych pętli do wykonania tego samego zadania.
Poniższy kod zapętla tabelę „zabiegów”. Przy każdym zabiegu przegląda listę „drzew”. Po znalezieniu dopasowania między polami leczenia i drzewami następuje selekcja w warstwie drzewa. Po znalezieniu dopasowania dla leczenia kod nie kontynuuje przeszukiwania warstwy drzewa w poszukiwaniu dodatkowych dopasowań. Wraca do tabeli leczenia, wybiera następny zabieg i ponownie przeszukuje klasę drzewa.
Sam kod działa dobrze, ale jest bolesnie wolny. „Tabela leczenia” w tym przypadku ma 16 000 rekordów. Klasa obiektów „drzewo” ma 60 000 rekordów.
Czy istnieje inny bardziej skuteczny sposób na odtworzenie tego, co robi ESRI, gdy przesuwa zaznaczenie z jednej tabeli do drugiej? Czy powinienem tworzyć indeks dla tabel? UWAGA: Te dane są przechowywane w 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
Odpowiedzi:
Po pierwsze, tak, na pewno będziesz chciał się upewnić, że pola klucza głównego i klucza obcego są indeksowane w obu tabelach. Pozwala to DBMS planować i wykonywać zapytania dotyczące tych pól znacznie wydajniej.
Po drugie, wzywamy
SelectLayerByAttribute_management
w ciasną, zagnieżdżoną pętlę (raz na drzewo na zabieg). Jest to wysoce nieefektywne z kilku powodów:Zamiast tego
SelectLayerByAttribute_management
dokonaj refaktoryzacji kodu, aby zadzwonić tylko raz za pomocą skryptu, w którym zaznaczono wszystkie powiązane rekordy.Pożyczając funkcję z innej odpowiedzi dla logiki konstrukcji whereclause, wyobrażam sobie, że wyglądałoby to tak:
Możesz to tak nazwać:
selectRelatedRecords(treatment_tv, tree_fl, "Facility_ID", "FACILITYID")
Uwagi:
To używa
arcpy.da.SearchCursor
, dostępne tylko w 10.1. Jak wspomniano @PolyGeo, kursory te są znacznie szybsze niż ich poprzednicy (arcpy.SearchCursor
). Można go jednak łatwo zmodyfikować, aby używał starego SearchCursor:Jeśli twoja geobaza SDE znajduje się na Oracle, ostrzeż, że
IN
instrukcja użyta w funkcji z połączonej odpowiedzi jest ograniczona do 1000 elementów. Jedno z możliwych rozwiązań jest opisane w tej odpowiedzi , ale trzeba by zmodyfikować funkcję, aby podzielić ją na wieleIN
instrukcji o długości 1000 zamiast jednej.źródło
Powyższe rozwiązanie działa dla mnie świetnie i było bardzo szybkie. Używając powyższego kodu i kodu z drugiego postu, zbudowałem go w następujący sposób:
źródło