Django LayerMapping: как отфильтровать файл формы перед сохранением в базу данных - PullRequest
1 голос
/ 29 января 2020

У меня есть файл формы, который я хочу импортировать в базу данных django, используя модуль Django -LayerMapping ( Ссылка на модуль ), потому что он преобразует пространственные данные в Geo Django модели. Ванильный способ импортировать файл формы в базу данных в соответствии с учебником 1004 * выглядит следующим образом:

lm = LayerMapping(table, path, mapping, transform=True , encoding='utf-8') # load shape-file
lm.save(verbose=True) # save entire file to db

Но в моем случае таблица, в которую я хочу импортировать форму -файл данных не пуст. Я хочу добавить только те строки (или объекты в файле формы lin go) в БД, которых еще нет. Тем не менее, LayerMapping предоставляет только метод для сохранения всего файла формы в БД, а не отдельных записей, что приведет к дублированию в моем случае.

Таким образом, мой вопрос таков: как я могу отфильтровать записи объекта отображения слоя перед его сохранением?

До сих пор я думал о двух возможных решениях:

  1. Отфильтруйте записи в объекте отображения слоев и сохраните весь объект с помощью предоставленного метода .save (). Но я не знаю, как удалить отдельные записи из объекта отображения слоя.

  2. Перебирать все записи в объекте отображения слоя и проверять каждую из них, если она уже присутствует в базе данных. и только сохранить его, если его нет. Однако я не нашел метода отображения слоев для сохранения отдельных записей в БД. Можно было бы просто прочитать атрибуты и создать объекты самостоятельно, но тогда у меня не было бы доступа к преобразованию координат, которое было первоначальной причиной использования модуля отображения слоев.

Таким образом, вопрос остается прежним: как я могу отфильтровать этот объект отображения слоев перед его сохранением?

1 Ответ

0 голосов
/ 03 февраля 2020

Опция, которую стоит попробовать с LayerMapping, - это аргумент unique, который:

Установка в качестве имени или кортежа имен из данной модели , создаст модели, уникальные только для заданных имен. Геометрия от каждого объекта будет добавлена ​​в коллекцию, связанную с уникальной моделью . Принудительно устанавливает режим транзакции 'autocommit'.

. Проверяя код , выполненный в случае существующего имени unique, мы видим, что он пытается добавить данную геометрию к любые существующие записи:

if self.unique:
    # If we want unique models on a particular field, handle the
    # geometry appropriately.
    try:
        # Getting the keyword arguments and retrieving
        # the unique model.
        u_kwargs = self.unique_kwargs(kwargs)
        m = self.model.objects.using(self.using).get(**u_kwargs)
        is_update = True

        # Getting the geometry (in OGR form), creating
        # one from the kwargs WKT, adding in additional
        # geometries, and update the attribute with the
        # just-updated geometry WKT.
        geom_value = getattr(m, self.geom_field)
        if geom_value is None:
            geom = OGRGeometry(kwargs[self.geom_field])
        else:
            geom = geom_value.ogr
            new = OGRGeometry(kwargs[self.geom_field])
            for g in new:
                geom.add(g)
            setattr(m, self.geom_field, geom.wkt)
    except ObjectDoesNotExist:
        # No unique model exists yet, create.
        m = self.model(**kwargs)

Если это то, что соответствует вашим потребностям в качестве функциональности, то вы можете попробовать уникальный вариант следующим образом:

lm = LayerMapping(
    table, 
    path, 
    mapping, 
    transform=True , 
    unique=('field_name_1', 'field_name_2', ...), 
    encoding='utf-8'
)

Если вышеприведенное не соответствует потребностям вашего проекта, тогда указанные вами параметры будут работать нормально.

...