[postgresql] 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 도구 솔루션이 더 낫지 만). pgAdmin III을 시도했지만이 옵션을 찾을 수 없습니다.



답변

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

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


답변

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 수퍼 유저 권한이 필요하지 않음을 의미합니다.


답변

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

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

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

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

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

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

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


답변

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

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


답변

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

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


답변

@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과 동등한 것을 발견했다.


답변

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

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