Как работать с выборками

Вопросы связанные с работой ГИС Аксиома
Ответить
Аватара пользователя
pahanbl4
Сообщения: 23
Зарегистрирован: 11 окт 2019, 08:55

Как работать с выборками

Сообщение pahanbl4 » 11 окт 2019, 09:35

Здравствуйте! Помогите с "парой" моментов:

Код: Выделить всё

    history_snapshot = HistorySnapshot(table.featureIdComparator())
    
    it = mapView.selectionModel().selectedItems()[0]
    layer = it.layer()
    style_index = layer().tableSchema().styleIndex()
    
    # получаем записи из выборки
    selMan = self._gui().selectionManager()
    cursor = selMan.readSelectedFeaturesData()
    ids = [feature.id() for feature in cursor]
    attrs = table.attributeNames()
    features = table.selectFeaturesById(ids, attrs)

    # сохраняем статусы записей
    modif = [feature.modifiedStatus() for feature in features]

    try:
      # Так изменяем значения полей и стиль (для примера)
      for feature in features:
        feature.setAttribute(name, value, Qt.CaseInsensitive)
        feature.setModified(name, True, Qt.CaseInsensitive)
        mi_style = MapBasicStyle().styleFromString(style)
        feature.setAttribute(style_index, mi_style)
        feature.setModified(style_index, True)
    finally:
      # сохраняем изменения (если они были)
      for i in range(0, len(features)):
        if modif[i] != features[i].modifiedStatus():
          history_snapshot.storeUpdatedFeature(feature)
      table.save(history_snapshot)
      layer.needRedraw.emit(layer)
1) Как правильно работать с выборкой? Как получить записи из выборки? Я правильно делаю?
2) Как правильно получить измененные записи и сохранить только их?
3) Есть ли возможность применить и отобразить изменения без сохранения таблицы?
Сейчас у меня изменения сохраняются только после сохранения таблицы.. это недопустимо.

Код: Выделить всё

    it = mapView.selectionModel().selectedItems()[0]
    table = it.table()
    context = SimpleTableContext(table)
    cmd = 'UPDATE Выборка SET Протяженность_км = ObjLen(obj, "km")'
    res = update(cmd, context)
4) Почему не работает обновление через запрос для выборки? Что я не так делаю?
Если тоже самое сделать для всей таблицы - работает..
Аватара пользователя
Артём
Сообщения: 12
Зарегистрирован: 07 июн 2019, 11:48

Re: Как работать с выборками

Сообщение Артём » 11 окт 2019, 11:44

Я могу предположить, что для решения этой задачи не надо создавать HistorySnapshot и вызывать метод save. Это низкоуровневый механизм, и он предназначен именно для записи таблицы на диск.

Вместо этого вызывайте метод table.update(features). Он создаст новую транзакцию, которая будет храниться в транзакционном файле и не попадёт на диск, пока не будет вызван метод table.commit(). Для перемещения по истории транзакций можно воспользоваться методами rollBack, rollForward, setCurrentChangeIndex.
4) Почему не работает обновление через запрос для выборки? Что я не так делаю?
Какой версией Аксиомы вы пользуетесь? Обновление выборки через SQL-запрос появилось только в версии 2.3.2.
Проверьте, работает ли такой запрос, если его выполнить через GUI (инструмент "Обновить колонку").
Если не работает, то какую ошибку выдаёт?
Аватара пользователя
pahanbl4
Сообщения: 23
Зарегистрирован: 11 окт 2019, 08:55

Re: Как работать с выборками

Сообщение pahanbl4 » 12 окт 2019, 09:28

Как раз пользуюсь версией 2.3.2 :geek:
Через обновить колонку работает.
Если забить в консоли - нет:

Код: Выделить всё

table = axioma.app.mainWindow.mapViewManager().currentMapView().selectionModel().selectedItems()[0].table()
context = axioma.core.sql.SimpleTableContext(table)
cmd = 'UPDATE Выборка SET Протяженность_сооружения_км = ObjectLen(obj, "km")'
res = axioma.core.sql.update(cmd, context)
если обновление делать на всю таблицу из которой выборка - отрабатывает
Вместо этого вызывайте метод table.update(features). Он создаст новую транзакцию, которая будет храниться в транзакционном файле и не попадёт на диск, пока не будет вызван метод table.commit(). Для перемещения по истории транзакций можно воспользоваться методами rollBack, rollForward, setCurrentChangeIndex.
Спасибо! Так намного лучше.
Аватара пользователя
Артём
Сообщения: 12
Зарегистрирован: 07 июн 2019, 11:48

Re: Как работать с выборками

Сообщение Артём » 15 окт 2019, 09:57

pahanbl4 писал(а): 12 окт 2019, 09:28

Код: Выделить всё

table = axioma.app.mainWindow.mapViewManager().currentMapView().selectionModel().selectedItems()[0].table()
context = axioma.core.sql.SimpleTableContext(table)
cmd = 'UPDATE Выборка SET Протяженность_сооружения_км = ObjectLen(obj, "km")'
res = axioma.core.sql.update(cmd, context)

В этом примере берётся не та таблица. Записи в массиве selectedItems() ссылаются на исходную таблицу, из которой произведена выборка. А таблица с названием Выборка - она создаётся как обёртка над исходной таблицей.

Чтобы получить таблицу с именем Выборка, вызывайте метод класса DataCatalog:

Код: Выделить всё

table = axioma.app.mainWindow.dataCatalog().selectionTable()
context = axioma.core.sql.SimpleTableContext(table)
После этого убедитесь, что SQL-контекст содержит таблицу с правильным именем:
>>> print(context.allTablesNames())
['Выборка']

По идее, как-то можно вообще обойтись без создания своего SQL-контекста и сделать так, чтобы Аксиома использовала общесистемный контекст (со всеми доступными таблицами), но пока что эта возможность не вынесена в API для разработчиков на Python
Аватара пользователя
pahanbl4
Сообщения: 23
Зарегистрирован: 11 окт 2019, 08:55

Re: Как работать с выборками

Сообщение pahanbl4 » 16 окт 2019, 09:54

Спасибо!
Ответить