Экспорт определенных строк из таблицы PostgreSQL в виде сценария INSERT SQL

У меня есть схема базы данных с именем: nyummy и таблица с именем cimory:

create table nyummy.cimory (
  id numeric(10,0) not null,
  name character varying(60) not null,
  city character varying(50) not null,
  CONSTRAINT cimory_pkey PRIMARY KEY (id)
);

Я хочу экспортировать данные таблицы cimory в виде файла сценария SQL для вставки. Тем не менее, я хочу экспортировать только записи / данные, где город равен «токио» (предположим, что все данные о городе в нижнем регистре).

Как это сделать?

Неважно, находится ли решение в бесплатных инструментах с графическим интерфейсом пользователя или в командной строке (хотя инструменты с графическим интерфейсом лучше). Я пробовал pgAdmin III, но не могу найти возможности сделать это.


person null    schedule 10.10.2012    source источник
comment
PostgreSQL не может выбирать между базами данных. По крайней мере, старые версии не могут, как и Greenplum, не знаю о 9.x.   -  person PhilHibbs    schedule 17.02.2017
comment
Я понимаю, что это устарело, но я просто хотел упомянуть, что можно выбирать между базами данных с помощью dblink, который доступен по крайней мере с версии v8.3. Он использует сторонние серверы и сторонние оболочки данных для подключения к удаленным базам данных. Это работает независимо от того, существуют ли эти базы данных на одном экземпляре или на совершенно разных хостах. Я довольно широко использовал его для создания материализованных представлений в других базах данных, чтобы облегчить определенные отчеты и тому подобное, и он отлично работает.   -  person G_Hosa_Phat    schedule 05.03.2020


Ответы (10)


Создайте таблицу с набором, который вы хотите экспортировать, а затем используйте утилиту командной строки pg_dump для экспорта в файл:

create table export_table as 
select id, name, city
from nyummy.cimory
where city = 'tokyo'
$ pg_dump --table=export_table --data-only --column-inserts my_database > data.sql

--column-inserts будет выгружать как команды вставки с именами столбцов.

--data-only не выгружайте схему.

Как прокомментировано ниже, создание представления вместо таблицы позволит избежать создания таблицы всякий раз, когда необходим новый экспорт.

person Clodoaldo Neto    schedule 10.10.2012
comment
Хорошо, пока ваше решение работает. Я упустил одну вещь: мне нужно добавить -U имя_пользователя. Я также почти преуспел с инструментом ToraSQL, просто у него есть ошибка в данных даты и времени в результате скрипта. Если никто не сможет предоставить решение для графического интерфейса в течение 2 дней, ваш ответ будет принят. - person null; 10.10.2012
comment
Просто хотите поделиться с другими людьми, вы также можете использовать этот бесплатный инструмент с графическим интерфейсом: SQL Workbench / J (с драйвером postgreSQL jdbc4), чтобы сделать то же самое. - person null; 11.10.2012
comment
Это было бы намного лучше с create view export_view..., так как представление будет оставаться актуальным с изменениями в базовой таблице. В документах написано --table=table: Dump only tables (or **views**..., поэтому у меня была некоторая надежда, что это сработает , но сброс представления, к сожалению, не дает никаких данных. :П - person poshest; 20.11.2016
comment
@poshest У меня работает в 9.5. Что именно вы пробовали? - person Clodoaldo Neto; 20.11.2016
comment
@ClodoaldoNeto о, хорошо, отлично! Надеюсь, я тоже смогу заставить его работать. Я использовал pg_dump --table=my_schema.my_view --data-only --inserts my_db > data.sql, версию 9.5.3, и мой create оператор был таким же, как ваш, за исключением create view.... Все, что я получаю, - это обычные комментарии pg_dump и операторы SET. Не уверен, где я ошибаюсь. - person poshest; 20.11.2016
comment
@poshest Если таблица пуста или условие where отфильтровывает все строки, то в выводе pg_dump не будет строк. - person Clodoaldo Neto; 21.11.2016
comment
@ClodoaldoNeto определенно есть данные в таблице, и выбор из представления в PG Admin дает данные. Изменение my_view в моем операторе pg_dump выше на my_table (на котором основан my_view) также работает. Я не уверен, что делаю не так. Хотя знать, что он МОЖЕТ работать, - это здорово. Я буду продолжать попытки и доложу, когда у меня получится. - person poshest; 22.11.2016
comment
Это решение - работа. Из этого решения в файле sql имя таблицы - export_table. Но исходное имя таблицы - nyummy.cimory. Возьмем производственную БД и сервер БД УАТ. На обоих серверах БД у меня есть схема nyummy и таблица cimory. Мне нужно сделать дамп для определенных строк из производственной таблицы cimory в таблицу cimory UAT. Для этого мне нужно создать одну таблицу export_table, а затем изменить имя таблицы в файле sql. Затем мне нужно скопировать данные в таблицу UAT. Итак, есть ли способ получить дамп для определенных строк из таблицы. - person Nivetha Jaishankar; 02.04.2018
comment
Итак, есть ли способ получить дамп для определенных строк из производственной таблицы. Если возможно, мы можем легко скопировать данные в UAT. Нет необходимости создавать дополнительную таблицу в производственной базе данных. - person Nivetha Jaishankar; 02.04.2018
comment
Я хочу сделать это для нескольких таблиц и хочу хранить их операторы вставки в одном файле. поэтому, если я динамически сгенерирую команду pg_dump для каждой таблицы, а затем выполню ее, будет ли она добавляться в тот же файл или перезаписываться? - person Udit Solanki; 03.03.2019
comment
ок. отвечая на мой собственный вопрос .. вы можете сбросить несколько таблиц, используя несколько предложений --table. - person Udit Solanki; 03.03.2019

Для экспорта данных используйте только _1 _ :

COPY (SELECT * FROM nyummy.cimory WHERE city = 'tokio') TO '/path/to/file.csv';

Вы можете экспортировать всю таблицу, только выбранные столбцы или результат запроса, как показано. Не нужно явно создавать таблицу.

Вы получаете файл с одной строкой таблицы в строке в виде обычного текста (не INSERT команд). Меньше и быстрее, чем INSERT команды.

Чтобы импортировать то же самое в другую таблицу Postgres с соответствующей структурой в любом месте (столбцы в том же порядке, типы данных совместимы!):

COPY other_tbl FROM '/path/to/file.csv';

COPY записывает и читает файлы локально для сервера, в отличие от клиентских программ, таких как pg_dump или psql, которые читают и записывают файлы локально для клиента. Если оба работают на одной машине, это не имеет большого значения, но имеет значение для удаленных подключений.

Также существует команда \copy для psql < / strong>:

Выполняет внешнюю (клиентскую) копию. Это операция, запускающая SQL COPY , но вместо того, чтобы сервер считывал или записывал указанный файл, psql считывает или записывает файл и направляет данные между сервером и локальной файловой системой. Это означает, что доступ к файлам и привилегии принадлежат локальному пользователю, а не серверу, и привилегии суперпользователя SQL не требуются.

Тот же синтаксис, что и выше. Просто замените COPY на \copy.

person Erwin Brandstetter    schedule 10.10.2012
comment
OP вызывает специально для данных как вставить файл сценария sql. Я думаю, он говорит о insert командах, не так ли? - person Clodoaldo Neto; 10.10.2012
comment
@Clodoaldo: Возможно, вы правы, и в этом случае ваш ответ будет более подходящим. Можно также отдельно скопировать сценарий CREATE в pgAdmin (поскольку OP упоминает GUI). - person Erwin Brandstetter; 10.10.2012
comment
STDIN и STDOUT можно использовать вместо пути к файлу, что полезно для экспорта небольших данных. - person Amir Ali Akbari; 06.01.2015
comment
Без флага --column-inserts pg_dump использует COPY из STDIN для каждой таблицы в генерируемом им коде SQL. - person Randall; 26.10.2016
comment
Позаботьтесь о том, чтобы порядок выбранных столбцов соответствовал порядку столбцов в целевой базе данных. Если этого не произойдет, это может привести к сбою или, что еще хуже, к успеху, но при вставке неверных данных. - person Nathan Wallace; 09.07.2018
comment
Существует проблема, из-за которой порядок столбцов в исходной и целевой базе данных Postgres должен быть таким же, поскольку команда копирования не сообщает, в какой столбец следует добавить данные. Если столбцы в целевой БД расположены в неправильном порядке, при импорте данных возникнут проблемы. В запросах на вставку такой проблемы нет. - person Ismail Iqbal; 22.06.2021

Это простой и быстрый способ экспортировать таблицу в сценарий с помощью pgAdmin вручную без дополнительных установок:

  1. Щелкните правой кнопкой мыши целевую таблицу и выберите «Резервное копирование».
  2. Выберите путь к файлу для хранения резервной копии. В качестве формата выберите «Обычный».
  3. Откройте вкладку «Параметры дампа # 2» внизу и отметьте «Использовать вставки столбцов».
  4. Нажмите кнопку Backup.
  5. Если вы откроете полученный файл с помощью текстового ридера (например, блокнота ++), вы получите скрипт для создания всей таблицы. Оттуда вы можете просто скопировать сгенерированные инструкции INSERT.

Этот метод также работает с техникой создания export_table, как показано в ответе @Clodoaldo Neto.

«Щелкните

Выберите путь назначения и измените формат на Обычный

Откройте вкладку Dump Options # 2 внизу и установите флажок Use Column Inserts

Вы можете скопировать оттуда инструкции INSERT.

person Andi R    schedule 15.08.2016
comment
Когда я это делаю, опции Bakckup нет. Это pgAdmin III v1.18.1, подключающийся к Greenplum 4.3.4.1 (на основе PostgreSQL 8.2.15). - person PhilHibbs; 17.02.2017
comment
Я установил pgAdmin III v1.18.1 и там был вариант резервного копирования. Я подключился к PostgreSQL 9.5. Так что проблема, скорее всего, между pgAdmin и Greenplum. - person Andi R; 22.02.2017
comment
Работает так, как задумано в pgAdmin4 - person Nikhil; 28.05.2020

Для моего варианта использования я мог просто передать grep.

pg_dump -U user_name --data-only --column-inserts -t nyummy.cimory | grep "tokyo" > tokyo.sql
person M.Vanderlee    schedule 25.08.2015
comment
Надо подумать о том, чтобы иметь «токио» в другой сфере. - person Buyut Joko Rivai; 09.01.2016
comment
@BuyutJokoRivai, так как это дамп только таблицы, в большинстве случаев все должно быть в порядке - person Ismail Iqbal; 24.04.2017
comment
Самый хитрый способ среди прочих по делу ‹3 - person Nam G VU; 21.07.2018
comment
Хотя с большой таблицей вы сбросите все строки для grep, что является ловушкой для вашего решения. Затем мы запрашиваем и сохраняем результат в таблицу для дампа, как здесь stackoverflow.com/a/12816187/248616: более удобный - person Nam G VU; 21.07.2018

SQL Workbench имеет такую ​​функцию.

После выполнения запроса щелкните правой кнопкой мыши результаты запроса и выберите «Копировать данные как SQL> Вставить SQL».

person machinery    schedule 27.11.2013
comment
Отлично работает. Когда вы выбираете «postgres» в качестве «драйвера», вероятно, вам придется загрузить драйверы JDBC самостоятельно: jdbc.postgresql.org/download.html (это файл .jar - двоичный файл java) и добавьте его в качестве« драйвера »соединения postgresql. Строка подключения (или URL-адрес, как в интерфейсе) должна выглядеть так: jdbc: postgresql: //127.0.0.1: 5432 / db_name - person mrmuggles; 13.07.2016
comment
DBVisualizer имеет аналогичную отличную функцию, которая позволяет копировать в файл или прямо в буфер обмена. - person Noumenon; 18.01.2017

Я попытался написать процедуру, делающую это, на основе кодов @PhilHibbs другим способом. Пожалуйста, посмотрите и проверьте.

 CREATE OR REPLACE FUNCTION dump(IN p_schema text, IN p_table text, IN p_where text)
   RETURNS setof text AS
 $BODY$
 DECLARE
     dumpquery_0 text;
     dumpquery_1 text;
     selquery text;
     selvalue text;
     valrec record;
     colrec record;
 BEGIN

     -- ------ --
     -- GLOBAL --
     --   build base INSERT
     --   build SELECT array[ ... ]
     dumpquery_0 := 'INSERT INTO ' ||  quote_ident(p_schema) || '.' || quote_ident(p_table) || '(';
     selquery    := 'SELECT array[';

     <<label0>>
     FOR colrec IN SELECT table_schema, table_name, column_name, data_type
                   FROM information_schema.columns
                   WHERE table_name = p_table and table_schema = p_schema
                   ORDER BY ordinal_position
     LOOP
         dumpquery_0 := dumpquery_0 || quote_ident(colrec.column_name) || ',';
         selquery    := selquery    || 'CAST(' || quote_ident(colrec.column_name) || ' AS TEXT),';
     END LOOP label0;

     dumpquery_0 := substring(dumpquery_0 ,1,length(dumpquery_0)-1) || ')';
     dumpquery_0 := dumpquery_0 || ' VALUES (';
     selquery    := substring(selquery    ,1,length(selquery)-1)    || '] AS MYARRAY';
     selquery    := selquery    || ' FROM ' ||quote_ident(p_schema)||'.'||quote_ident(p_table);
     selquery    := selquery    || ' WHERE '||p_where;
     -- GLOBAL --
     -- ------ --

     -- ----------- --
     -- SELECT LOOP --
     --   execute SELECT built and loop on each row
     <<label1>>
     FOR valrec IN  EXECUTE  selquery
     LOOP
         dumpquery_1 := '';
         IF not found THEN
             EXIT ;
         END IF;

         -- ----------- --
         -- LOOP ARRAY (EACH FIELDS) --
         <<label2>>
         FOREACH selvalue in ARRAY valrec.MYARRAY
         LOOP
             IF selvalue IS NULL
             THEN selvalue := 'NULL';
             ELSE selvalue := quote_literal(selvalue);
             END IF;
             dumpquery_1 := dumpquery_1 || selvalue || ',';
         END LOOP label2;
         dumpquery_1 := substring(dumpquery_1 ,1,length(dumpquery_1)-1) || ');';
         -- LOOP ARRAY (EACH FIELD) --
         -- ----------- --

         -- debug: RETURN NEXT dumpquery_0 || dumpquery_1 || ' --' || selquery;
         -- debug: RETURN NEXT selquery;
         RETURN NEXT dumpquery_0 || dumpquery_1;

     END LOOP label1 ;
     -- SELECT LOOP --
     -- ----------- --

 RETURN ;
 END
 $BODY$
   LANGUAGE plpgsql VOLATILE;

А потом :

-- for a range
SELECT dump('public', 'my_table','my_id between 123456 and 123459'); 
-- for the entire table
SELECT dump('public', 'my_table','true');

протестировано на моем postgres 9.1 с таблицей со смешанным типом данных поля (текст, double, int, отметка времени без часового пояса и т. д.).

Вот почему необходим тип CAST in TEXT. Мой тест прошел правильно примерно для 9 миллионов строк, похоже, что он не прошел незадолго до 18 минут работы.

ps: Я нашел эквивалент mysql в Интернете.

person Vi Shen    schedule 24.05.2018

Вы можете просмотреть таблицу с указанными записями, а затем выгрузить файл sql

CREATE VIEW foo AS
SELECT id,name,city FROM nyummy.cimory WHERE city = 'tokyo'
person Giorgi Peikrishvili    schedule 10.10.2012
comment
Я пробовал это в pgAdmin III, но для объекта View нет опции для сброса. - person null; 10.10.2012
comment
Попробуйте навигат. Я использую его, и у него есть опция экспорта сценария sql - person Giorgi Peikrishvili; 10.10.2012
comment
@Giorgi: есть ли бесплатная версия? - person null; 10.10.2012
comment
Невозможно использовать Postgres 9.1 - person HCarrasko; 02.02.2015

Я просто придумал для этого быструю процедуру. Он работает только для одной строки, поэтому я создаю временное представление, которое просто выбирает нужную мне строку, а затем заменяю pg_temp.temp_view фактической таблицей, в которую я хочу вставить.

CREATE OR REPLACE FUNCTION dv_util.gen_insert_statement(IN p_schema text, IN p_table text)
  RETURNS text AS
$BODY$
DECLARE
    selquery text; 
    valquery text; 
    selvalue text; 
    colvalue text; 
    colrec record;
BEGIN

    selquery := 'INSERT INTO ' ||  quote_ident(p_schema) || '.' || quote_ident(p_table);

    selquery := selquery || '(';

    valquery := ' VALUES (';
    FOR colrec IN SELECT table_schema, table_name, column_name, data_type
                  FROM information_schema.columns 
                  WHERE table_name = p_table and table_schema = p_schema 
                  ORDER BY ordinal_position 
    LOOP
      selquery := selquery || quote_ident(colrec.column_name) || ',';

      selvalue := 
        'SELECT CASE WHEN ' || quote_ident(colrec.column_name) || ' IS NULL' || 
                   ' THEN ''NULL''' || 
                   ' ELSE '''' || quote_literal('|| quote_ident(colrec.column_name) || ')::text || ''''' || 
                   ' END' || 
        ' FROM '||quote_ident(p_schema)||'.'||quote_ident(p_table);
      EXECUTE selvalue INTO colvalue;
      valquery := valquery || colvalue || ',';
    END LOOP;
    -- Replace the last , with a )
    selquery := substring(selquery,1,length(selquery)-1) || ')';
    valquery := substring(valquery,1,length(valquery)-1) || ')';

    selquery := selquery || valquery;

RETURN selquery;
END
$BODY$
  LANGUAGE plpgsql VOLATILE;

Вызывается таким образом:

SELECT distinct dv_util.gen_insert_statement('pg_temp_' || sess_id::text,'my_data') 
from pg_stat_activity 
where procpid = pg_backend_pid()

Я не тестировал это против инъекционных атак, дайте мне знать, если вызова quote_literal для этого недостаточно.

Также он работает только для столбцов, которые можно просто преобразовать в :: text и обратно.

Также это для Greenplum, но я не могу придумать причину, по которой он не работает на Postgres, CMIIW.

person PhilHibbs    schedule 17.02.2017

Мне нужен был способ создания операторов вставки без создания временной таблицы (в производстве). Я видел некоторые полезные аргументы в пользу pg_dump выше, но все же в конечном итоге придумал способ

генерировать операторы вставки и выгружать в файл

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

$ /usr/local/bin/pg_dump -h the_db_host_address -d the_db_name --table=schema_name.table_name --data-only --column-inserts -U postgres -p the_port_number -v -f /Users/the_user/folder_name/insrt_stmts_file_name.sql

Следующее - это приглашение, которое запрашивает пароль. В приведенном выше случае я предоставил пароль postgres, но любой другой пользователь, у которого есть возможность чтения, должен работать нормально.

Я запустил только операторы вставки из файла с именем: insrt_stmts_file_name.sql в клиенте DBeaver.

Но то же самое можно запустить и из командной строки, используя следующий скрипт:

/usr/local/bin/psql -h the_db_host_address -d the_db_name -v -U postgres -f /Users/the_user/folder_name/insrt_stmts_file_name.sql

Справочник по флагам pg_dump / psql: -h = host -d = db name -v = verbose (выводится по мере продвижения) -U = db user name -f = file / path

person Nirmal    schedule 04.05.2021

Вы пробовали в pgadmin выполнить запрос с " EXECUTE QUERY WRITE RESULT TO FILE " option

его только экспортируют данные, иначе попробуйте как

pg_dump -t view_name DB_name > db.sql

Параметр -t, используемый для ==> Дамп только таблиц (или представлений, или последовательностей) таблицы соответствия, ссылаться

person solaimuruganv    schedule 10.10.2012
comment
Будет экспортирован только create view оператор. - person cdmckay; 02.07.2014