Экспорт определенных строк из таблицы 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. Однако я хочу экспортировать только записи / данные, где город равен "Токио" (предположим, что данные города все строчные).
как это сделать?
не имеет значения, находится ли решение в бесплатных инструментах GUI или командной строке (хотя решение GUI tools лучше). Я пытался pgAdmin попробуйте III, но я не могу найти вариант сделать это.
9 ответов
создайте таблицу с набором, который вы хотите экспортировать, а затем используйте утилиту командной строки pg_dump для экспорта в файл:
create table export_table as
select id, name, city
from nyummy.cimory
where city = 'tokio'
$ pg_dump --table=export_table --data-only --column-inserts my_database > data.sql
--column-inserts
будет сбрасываться как команды вставки с именами столбцов.
--data-only
не сбрасывать схему.
как указано ниже, создание представления вместо таблицы позволит избежать создания таблицы при необходимости нового экспорта.
на экспорт только данных использовать COPY
.
Вы получаете файл с одной строкой таблицы в строке в виде обычного текста (не INSERT
команды), он меньше и быстрее:
COPY (SELECT * FROM nyummy.cimory WHERE city = 'tokio') TO '/path/to/file.csv';
импорт то же самое для другой таблицы той же структуры в любом месте с:
COPY other_tbl FROM '/path/to/file.csv';
COPY
пишет и читает файлы локальный сервер, в отличие от клиентских программ, как pg_dump
или psql
читать и запись файлов локальные для клиента. Если оба работают на одной машине, это не имеет большого значения, но для удаленных подключений.
есть еще \copy
команда psql что:
выполняет копию интерфейса (клиента). Это операция, которая выполняется В SQL
COPY
команда, но вместо чтения или записи сервера указанный файл, psql считывает или записывает файл и направляет данные между сервером и локальная файловая система. Это означает, что файл доступность и привилегии принадлежат локальному пользователю, а не сервер, и никакие привилегии суперпользователя SQL не требуются.
Это легкий и быстрый способ экспорт таблицы в скрипт с помощью pgAdmin вручную без дополнительных установок:
- щелкните правой кнопкой мыши на целевой таблице и выберите "резервное копирование".
- указываете путь к файлу для сохранения резервной копии. В качестве формата выберите "Plain".
- откройте вкладку " Параметры дампа #2 "внизу и установите флажок"Использовать вставки столбцов".
- Нажмите кнопку резервное копирование.
- если вы откроете результирующий файл с текстовым считывателем (например, notepad++) вы получаете скрипт для создания всей таблицы. Оттуда вы можете просто скопировать сгенерированные инструкции INSERT -.
этот метод также работает с техникой создания export_table, как показано в ответе @Clodoaldo Neto.
SQL Workbench имеет такую функцию.
после выполнения запроса щелкните правой кнопкой мыши на результатах запроса и выберите "Копировать данные как SQL > SQL Insert"
для моего случая использования я смог просто передать grep.
pg_dump -U user_name --data-only --column-inserts -t nyummy.cimory | grep "tokyo" > tokyo.sql
вы можете сделать вид таблицы с записями specifit, а затем дамп sql file
CREATE VIEW foo AS
SELECT id,name,city FROM nyummy.cimory WHERE city = 'tokyo'
Я просто придумал быструю процедуру, чтобы сделать это. Он работает только для одной строки, поэтому я создаю временное представление, которое просто выбирает нужную строку, а затем заменяет 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 вызова недостаточно для этого.
также он работает только для столбцов, которые можно просто cast to:: text и обратно.
также это для Greenplum, но я не могу придумать причину, по которой он не будет работать на Postgres, CMIIW.
Я попытался написать процедуру, основанную на кодах @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, с таблицей со смешанным типом данных поля (text, double, int,timestamp без часового пояса и т. д.).
вот почему требуется приведение в текстовом типе. Мой тест выполняется правильно для строк 9M, похоже, что он терпит неудачу непосредственно перед 18 минутами работы.
ps : I нашел эквивалент для mysql в интернете.
вы пробовали в pgadmin выполнение запроса с " EXECUTE QUERY WRITE RESULT TO FILE "
опции
его единственный экспорт данных, иначе попробуйте как
pg_dump -t view_name DB_name > db.sql
-t опция используется для = = > дамп только таблицы (или представления или последовательности) таблицы соответствия,см.