Импорт / обновление существующих строк в PostgreSQL - PullRequest
2 голосов
/ 15 мая 2009

Я работаю над хобби-приложением, которое будет содержать большое количество жестко закодированных данных, а также динамические пользовательские данные после его развертывания. Мне нужна возможность локально обновлять жестко закодированные данные (больше UPDATE с, чем INSERT с), а затем экспортировать эти данные на сервер. Другими словами, мне нужно выгрузить данные в файл и импортировать их таким образом, чтобы новые строки (которых будет относительно немного) были INSERT обработаны, а существующие строки (как указано в PK) - UPDATE д. Ясно, что новые строки не могут быть INSERT отредактированы на сервере (или PK могут потенциально конфликтовать и выдавать ошибочные UPDATE s); это приемлемое ограничение. Однако я не могу DELETE строк быть UPDATE d, не говоря уже о удалении синхронизированных таблиц, поскольку таблицы, доступные для пользователя, будут иметь ограничения FK для «статических» таблиц.

К сожалению, это, кажется, очень сложно сделать. Списки рассылки Google и Postgres сообщают мне, что «MySQL-подобная» функция on_duplicate_key_update «будет в новой версии» (устаревшая информация; она есть?) Вместе с предложением «pg_loader can do it» без указания как .

В худшем случае я полагаю, что могу придумать домашнее решение (выгрузить файл данных, написать собственный скрипт импорта, который проверяет конфликты PK и выдает INSERT или UPDATE операторы соответственно) , но это кажется ужасно неуклюжим решением проблемы, с которой наверняка сталкивались другие до меня.

Есть мысли?

Ответы [ 4 ]

2 голосов
/ 17 мая 2009

Да, временная таблица + некоторая комбинация при вставке / обновлении - путь (вам не нужно делать это в функции, но вы можете).

Для записи, функция, которую вы ищете - это команда Merge. Кто-то написал патч для него, но он так и не был закончен. AFAIK никто не работает над этим сейчас; это, конечно, не в ближайшее время будет выпущен Postgres 8.4.

0 голосов
/ 20 мая 2009

Этот вопрос похож на this :

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

0 голосов
/ 15 мая 2009
create temporary table newdata as select * from table1 where false;

Заполните новые данные новыми данными, затем:

start transaction;
create function fill_table1() returns void as
$$
declare
    data record;
begin
    for data in select * from newdata
    loop
        update table1 set
            column1 = data.column1,
            column2 = data.column2
        where id = data.id
        if not found then
            insert into table1 values data.*;
        end if;
    end loop;
end;
$$ language plpgsql;
select fill_table();
drop function fill_table();
commit;

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

0 голосов
/ 15 мая 2009

Рассматривали ли вы запуск postgresql локально?

  1. Дамп данных сервера
  2. Импорт локально
  3. Включить ведение журнала запросов
  4. Сделать обновления
  5. Взять журнал запросов и запустить на сервере
  6. Очистить журнал запросов

Или я неправильно понимаю, что вы пытаетесь сделать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...