Как избежать дублирования GID при копировании объектов из одного слоя PostGIS в другой?


11

Когда я вношу новые элементы (функции) в другой слой Postgres, я могу сделать это двумя способами:

  1. Рисование новых элементов (с «Добавить объект»), которые я делаю редко или
  2. Копирование (или вырезание) некоторых элементов из другого слоя Postgre (исходного слоя) и вставка его в целевой слой, что я часто делаю

В первом примере, сохранение правок работает нормально , так как этот слой получает GID из Postgre последовательности базы данных * NEXTVAL ( «layer_name_gid_seq» :: regclass) *

Во втором примере я получил ошибку при сохранении правок, потому что при копировании элемента из исходного слоя в целевой слой qgis скопировал gid элемента из исходного слоя. При попытке сохранить изменения возвращается эта ошибка:

Не удалось зафиксировать изменения в слое «Cjevovodi».
Ошибки: ОШИБКА: 1 функция (и) не добавлена.
Ошибки провайдера:
ошибка PostGIS при добавлении функций: ОШИБКА: двойное значение ключа нарушает уникальное ограничение "cjevovodi_okill_pkey" ПОДРОБНЕЕ
: Ключ (gid) = (5) уже существует.

Я попытался скопировать * nextval ('layer_name_gid_seq' :: regclass) * в поле gid, но эту последовательность нельзя вставить в поле gid, так как поле определено как числовое.

Кто-нибудь знает простой способ скопировать элементы из исходного слоя (с существующим GID) назначить новый GID?

Спасибо!


Какую версию qgis и платформу вы используете? Я использую QGIS 2.0 в Windows 7, и у меня нет проблем с копированием между слоями постов.
Александр Нето

Вы когда-нибудь находили решение этой проблемы? Я сталкиваюсь с точно такой же проблемой. Я не хочу помещать триггер в PostgreSQL, когда QGIS не использует значения по умолчанию, когда новые функции создаются путем копирования других.
Получите Пространственное

Ответы:


4

Я не могу воспроизвести это в Windows QGIS 2.2, c3a2817.

Если другие версии ведут себя по-разному, или если у вас продолжает возникать эта проблема, вы, вероятно, можете установить триггер PostgreSQL на таблицу в качестве обходного пути:

Используя этот пример таблицы:

CREATE TABLE testing (gid serial PRIMARY KEY, geom geometry(Polygon, 4326));

Вот триггерная функция, которая назначит новую, gidгде это необходимо:

CREATE OR REPLACE FUNCTION testing_insert_trigger()
RETURNS trigger AS
$$
BEGIN
IF EXISTS (SELECT 1 FROM testing WHERE gid = NEW.gid) THEN
    NEW.gid := nextval('testing_gid_seq'::regclass);
END IF;
RETURN NEW;
END;
$$ language 'plpgsql';

Привязка функции к таблице ...

CREATE TRIGGER testing_insert 
BEFORE INSERT ON testing
FOR EACH ROW EXECUTE PROCEDURE testing_insert_trigger();

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

INSERT INTO testing (SELECT * FROM testing);

Конечно, этот подход может поставить под угрозу назначение вашего первичного ключа, поэтому используйте его осторожно.


0

Выберите объекты в исходном слое и сохраните выбранное (Save selected as ...) в шейп-файле. Добавьте сохраненный шейп-файл в проект QGIS и откройте таблицу атрибутов, затем удалите поле «gid» и сохраните шейп-файл. Выберите объекты в шейп-файле и скопируйте их на рабочий слой.


Спасибо за ваш ответ, но я пытаюсь найти более простой способ сделать это.
Хапа

1
если у вас есть таблица типа gid serial, int i, вы можете просто вставить i, и вы получите gid автоматически. У меня есть какая-то отдаленная память о том, что это возможно в QGIS, но я не могу вспомнить, как это сделать
симплексио
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.