PostgreSQL 테이블에서 특정 행을 INSERT SQL 스크립트로 내보내기


196

이름이 데이터베이스 스키마 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 도구 솔루션이 더 낫지 만). pgAdmin III을 시도했지만이 옵션을 찾을 수 없습니다.


2
INSERT 문을 건너 뛰고 데이터베이스간에 직접 SELECT를 사용하여 복사 할 수 있습니다. albertech.blogspot.com/2016/11/…
jar

PostgreSQL은 여러 데이터베이스를 선택할 수 없습니다. 적어도 구 버전은 Greenplum을 할 수 없으며, 9.x에 대해서는 모른다.
PhilHibbs

나는이 오래 실현,하지만 난 그냥 언급하고 싶었 입니다 사용하여 데이터베이스에서 선택할 수 DBLINK 적어도 V8.3부터 사용할 수있다. 외부 서버와 외부 데이터 래퍼를 사용하여 "원격"데이터베이스에 연결합니다. 이것은 해당 데이터베이스가 동일한 인스턴스에 있는지 또는 완전히 다른 호스트에 있는지 여부에 관계없이 작동합니다. 특정보고를 용이하게하기 위해 다른 데이터베이스에 구체화 된 뷰를 만드는 데 상당히 광범위하게 사용했으며 훌륭하게 작동했습니다.
G_Hosa_Phat

답변:


280

내보낼 세트로 테이블을 만든 다음 명령 줄 유틸리티 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 스키마를 덤프하지 마십시오.

아래에서 언급 한 것처럼 테이블 대신 뷰를 생성하면 새 내보내기가 필요할 때마다 테이블을 생성 할 필요가 없습니다.


3
자, 지금까지는 솔루션이 작동합니다. 한 가지 빠진 점은 "-U user_name"을 추가해야한다는 것입니다. 또한 ToraSQL 도구로 거의 성공했습니다. 스크립트 결과의 날짜-시간 데이터에 오류가있는 것입니다. 아무도 2 일 GUI 도구 솔루션을 제공 할 수 없다면, 당신의 대답은 허용되지 않습니다

2
다른 사람들과 공유하고 싶을 때이 무료 GUI 도구 인 SQL Workbench / J (postgreSQL jdbc4 드라이버 사용)를 사용하여 동일한 작업을 수행 할 수도 있습니다.
null

1
create view export_view...뷰가 기본 테이블을 변경하면 최신 상태로 유지되므로이 방법 이 훨씬 좋습니다 . 문서는 말을 --table=table: Dump only tables (or **views**...나는이 작업을 할 희망을했지만,보기를 덤핑하는 것은 슬프게도 데이터를 산출하지 않도록. : P
poshest

@poshest 9.5에서 작동합니다. 정확히 무엇을 시도 했습니까?
Clodoaldo Neto

@ClodoaldoNeto 아, 좋아요! 나는 또한 그것을 작동시킬 수 있기를 바랍니다. 나는 pg_dump --table=my_schema.my_view --data-only --inserts my_db > data.sql버전 9.5.3을 사용 했으며 내 create진술은을 제외하고는 당신과 동일했다 create view.... 출력에 얻는 것은 일반적인 pg_dump 주석과 SET문장입니다. 내가 잘못 가고 있는지 확실하지 않습니다.
poshest

176

A의 데이터 전용 내보내기 사용 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읽기 및 쓰기는 파일을 클라이언트에 지역 . 둘 다 동일한 컴퓨터에서 실행되는 경우 별 문제가되지 않지만 원격 연결에는 중요합니다.

\copypsql 명령 도 있습니다 :

프론트 엔드 (클라이언트) 복사를 수행합니다. 이것은 SQL COPY명령 을 실행하는 조작 이지만, 서버가 지정된 파일을 읽거나 쓰는 대신 psql이 파일을 읽거나 쓰고 서버와 로컬 파일 시스템간에 데이터를 라우트합니다. 이는 파일 액세스 가능성 및 권한이 서버가 아닌 로컬 사용자의 권한이며 SQL 수퍼 유저 권한이 필요하지 않음을 의미합니다.


10
OP는 특히 삽입 SQL 스크립트 파일로 데이터를 호출 합니다 . 그가 insert명령에 대해 이야기하고있는 것 같습니까?
Clodoaldo Neto

1
@Clodoaldo : 당신이 옳을 수도 있는데,이 경우 대답이 더 적합 할 것입니다. OP가 GUI를 언급 한 것처럼 pgAdmin에서 CREATE 스크립트를 별도로 복사 할 수도 있습니다.
Erwin Brandstetter

3
STDINSTDOUT작은 데이터 수출 유용한 파일 경로, 대신 사용할 수 있습니다.
Amir Ali Akbari

1
없이--column-inserts 플래그, pg_dump의는 사용 COPY이 생성하는 SQL 코드에서 테이블의 각 STDIN에서.
랜달

2
선택한 열 순서가 대상 데이터베이스의 열 순서와 일치하는지 확인하십시오. 그렇지 않으면 실패하거나 악화 될 수 있지만 잘못된 데이터를 삽입하십시오.
Nathan Wallace

32

이것은이다 쉽고 빠르게 하는 방법 pgAdmin와 스크립트에 테이블을 내보낼 수동으로 추가 설치없이 :

  1. 대상 테이블을 마우스 오른쪽 버튼으로 클릭하고 "백업"을 선택하십시오.
  2. 백업을 저장할 파일 경로를 선택하십시오. 형식으로 "일반"을 선택하십시오.
  3. 하단의 "덤프 옵션 # 2"탭을 열고 "열 삽입 사용"을 체크하십시오.
  4. 백업 버튼을 클릭하십시오.
  5. 텍스트 리더 (예 : notepad ++)로 결과 파일을 열면 전체 테이블을 작성하는 스크립트가 생성됩니다. 여기에서 생성 된 INSERT 문을 복사 할 수 있습니다.

이 방법은 @Clodoaldo Neto의 답변에 나와있는 것처럼 export_table을 만드는 기술과도 작동합니다.

대상 테이블을 마우스 오른쪽 버튼으로 클릭하고 "백업"을 선택하십시오.

대상 경로를 선택하고 형식을 "일반"으로 변경하십시오.

하단의 "덤프 옵션 # 2"탭을 열고 "열 삽입물 사용"을 확인하십시오.

여기에서 INSERT 문을 복사 할 수 있습니다.


이렇게하면 "Bakckup"옵션이 없습니다. Greenplum 4.3.4.1에 연결하는 pgAdmin III v1.18.1입니다 (PostgreSQL 8.2.15 기반).
PhilHibbs

나는 pgAdmin III의 v1.18.1를 설치하고이 있었다 "백업"옵션. PostgreSQL 9.5에 연결했습니다. 따라서 문제는 아마도 pgAdmin과 Greenplum 사이에 있습니다.
Andi R

pgAdmin4
Nikhil

9

SQL Workbench 에는 이러한 기능이 있습니다.

쿼리를 실행 한 후 쿼리 결과를 마우스 오른쪽 단추로 클릭하고 "SQL로 데이터 복사> SQL 삽입"을 선택하십시오.


1
잘 작동합니다. 'postgres'를 'driver'로 선택하면 JDBC 드라이버를 직접 다운로드해야 할 수 있습니다. jdbc.postgresql.org/download.html(.jar 파일 -java 바이너리 임) postgresql 연결의 '드라이버'. 연결 문자열 (또는 인터페이스의 URL)은 다음과 같아야합니다. jdbc : postgresql : //127.0.0.1 : 5432 / db_name
mrmuggles

DBVisualizer 에는 파일로 또는 클립 보드로 직접 복사 할 수있는 유사하고 뛰어난 기능이 있습니다.
Noumenon

8

내 유스 케이스의 경우 간단히 grep으로 파이프 할 수있었습니다.

pg_dump -U user_name --data-only --column-inserts -t nyummy.cimory | grep "tokyo" > tokyo.sql

2
다른 분야에서 '도쿄'를 갖는 것을 고려해야합니다.
Buyut Joko Rivai 2016 년

@BuyutJokoRivai 그것은 대부분의 경우에 테이블 덤프이기 때문에 괜찮을 것입니다
Ismail Iqbal

사건에서 다른 사람들 사이에서 가장 영리한 방법 <3
Nam G VU

큰 테이블을 사용하더라도 솔루션의 함정 인 grep에 대한 모든 행을 덤프합니다. 그런 다음 테이블로가는 길에 우리 쿼리 및 저장 결과로 여기 덤프 stackoverflow.com/a/12816187/248616은 더 suiteable이다
남 G VU

5

@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');

혼합 된 필드 데이터 유형 (텍스트, 이중, int, 시간대없는 타임 스탬프 등)이있는 표를 사용하여 postgres 9.1에서 테스트했습니다.

이것이 TEXT 유형의 CAST가 필요한 이유입니다. 약 9M 라인에서 테스트가 올바르게 실행되었습니다. 18 분 전에 실행이 실패한 것 같습니다.

추신 : 나는 웹에서 mysql과 동등한 것을 발견했다.


3

스펙 레코드를 사용하여 테이블을보고 SQL 파일을 덤프 할 수 있습니다.

CREATE VIEW foo AS
SELECT id,name,city FROM nyummy.cimory WHERE city = 'tokyo'

3
pgAdmin III에서 시도했지만 View 객체의 경우 덤프 옵션이 없습니다.
null

navicat을 사용해보십시오. 나는 그것을 사용하고 있는데 수출 SQL 스크립트 옵션이 있습니다
오르기 Peikrishvili을

@Giorgi : 프리웨어 버전이 있습니까?
null

Postgres 9.1
HCarrasko를

2

방금 간단한 절차를 시작했습니다. 단일 행에서만 작동하므로 원하는 행을 선택하는 임시 뷰를 만든 다음 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을위한 것이지만 CMIIW Postgres에서 작동하지 않는 이유를 생각할 수 없습니다.


-2

pgadmin에서 " EXECUTE QUERY WRITE RESULT TO FILE " 옵션으로 쿼리를 실행 해 보셨습니까?

데이터 만 내보내십시오. 그렇지 않으면 시도하십시오.

pg_dump -t view_name DB_name > db.sql

==> 사용 -t 옵션 만 테이블 (또는 뷰 또는 서열) 테이블 일치 덤프 참조


1
이것은 create view명령문 만 내보낼 것입니다
cdmckay
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.