arcpy.da.UpdateCursor повторно походит по записям в таблице

0 голосов
спросил 18 Окт, 17 от doujin (2,940 баллов) в категории Программные продукты Esri

Здравствуйте. Столкнулся со странным поведением курсора, который обновляет записи в таблице. Возможно, кто-то сталкивался с похожей проблемой и подскажет решение.

На сервере установлен ArcGIS for Server. В СУБД MS SQL создана база пространственных данных. В базе есть полигональный слой, который необходимо периодически обновлять на основании внешних шейп-файлов. Был подготовлен скрипт на python, который читает шейп-файлы и обновляет записи в базе данных, если выполняются определенные условия. Запускается скрипт на том же сервере.

Код метода для обновления:

class Dataset(object):
    def update(self, new_features):
        with arcpy.da.Editor(self.workspace):
            with arcpy.da.UpdateCursor(self.path, self.fields) as cursor:
                for row in cursor:
                    feature = Feature.create(self.fields, row)
                    if feature.id in new_features:
                        new_feature = new_features[feature.id]
                        if new_feature.date > feature.date:
                            cursor.updateRow(new_feature.as_row(self.fields))
                        else:
                            pass
                    else:
                        cursor.deleteRow()

 Проблема заключается в том, что курсор проходит по всем записям в таблице (обновляя, удаляя или пропуская каждую запись), а потом проходит по некоторым из обновленных записей повторно. Поясню на примере: в таблице всего 10000 записей. Курсор прошел по всем 10000, и еще раз по 200 обновленным записям. Причем иногда это может быть 10 лишних записей, иногда 800, а иногда и 0. Закономерность уследить не удалось. Почему курсор проходит по обновленным записям повторно?

Версия ArcGIS for Server 10.3.1, СУБД MS SQL Server 2012, скрипт подключается к базе под учетной записью владельца данных. Версионность для обновляемого слоя не включена, т.к. никто кроме владельца данных (скрипта) изменять данные не должен. Спасибо

1 Ответ

0 голосов
ответил 27 Ноя от greyzy (280 баллов)

Очень недавно в питоне, правильно ли понял: на вход функции подается шейп-файл (new_features) , курсор бежит по строкам БД по адресу (self.path),  создается объект feature, со строкой из БД (не нашел функцию Feature в справке кстати), если id в строке БД присутствует в шейп-файле (тоже не понятно мне по неопытности, может шейп-файл уже в виде списка или строки, как в шейп-файле число искать?smiley)  создается объект new_feature с такой же строкой из шейп-файла, и если данные свежЕе, то строка в БД обновляется данными из строки шейп-файла (зачем тут else: pass?), если такого id нет, строка удаляется вообще.

Мысли) Как определили, что по второму разу обрабатываются те же записи? Сопоставление идет по id, следует проверить, все ли id уникальны в шейп-файле, а главное в БД, нет ли дублеров (это я так понимаю не тот внутренний FID, который встроен и всегда уникален в шейп-файле или БД)? Два id - и вот уже две записи обновились. Ну и наконец, запускать это дело из отладчика с простановкой точек останова, и смотреть какие значения принимают feature.id, new_feature.date, feature.date. + бы поставил вывод чего там записалось в row после строки скрипта

cursor.updateRow(new_feature.as_row(self.fields))

...