Як уникнути дублювання GID під час копіювання функцій з одного шару PostGIS в інший?


11

Коли я ввожу нові елементи (функції) в інший шар Postgres, я можу це зробити двома способами:

  1. Малювання нових елементів (із "Додати функцію"), які я роблю рідко або
  2. Копіювати (або вирізати) деякі елементи з іншого шару Postgre (вихідний шар) і вставляти його в цільовий шар, який я часто роблю

У першому прикладі збереження змін працює нормально, оскільки цей шар отримує gid від послідовності бази даних postgre * nextval ('layer_name_gid_seq' :: regclass) *

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

Не вдалося здійснити зміни в шарі „Cjevovodi“
Помилки: ПОМИЛКА: 1 функція (и) не додана.
Помилки постачальника:
Помилка PostGIS під час додавання функцій: ПОМИЛКА: значення дубліката ключа порушує унікальне обмеження "cjevovodi_okill_pkey" ДЕТАЛІ
: Key (gid) = (5) вже існує.

Я намагався скопіювати * nextval ('layer_name_gid_seq' :: regclass) * у поле gid, але цю послідовність не можна вставити в поле gid, оскільки поле визначається як числове.

Хтось знає простий спосіб копіювання елементів з вихідного шару (з існуючим gid) присвоїти новий gid?

Дякую!


Яку версію qgis та платформи ви використовуєте? Я використовую QGIS 2.0 у Windows 7, і у мене, здається, немає проблем із вставкою копії між шарами пошти.
— Олександр Нето

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

Відповіді:


4

Я не в змозі відтворити це в QGIS 2.2 Windows, 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

Виберіть функції у вихідному шарі та збережіть вибране (Зберегти вибране як ...) у формі файла. Додайте збережений форм-файл у проект QGIS та відкрийте таблицю атрибутів, потім видаліть поле "gid" та збережіть shapefile. Виберіть функції у форм-файлі та скопіюйте їх у робочий шар.


Дякую за вашу відповідь, але я намагаюся знайти простіший спосіб зробити це.
— хапа

1
якщо у вас є таблиця типу gid serial, int i, ви можете просто вставити i, і ви отримаєте gid автоматично. у мене є якась віддалена пам'ять, що це можливо в QGIS, але я не можу пригадати, як це зробити
— simplexio
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.