INSERT SQL स्क्रिप्ट के रूप में एक PostgreSQL तालिका से विशिष्ट पंक्तियों को निर्यात करें


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एसक्यूएल स्क्रिप्ट फ़ाइल डालने के रूप में तालिका के डेटा को निर्यात करना चाहता हूं । हालांकि, मैं केवल रिकॉर्ड / डेटा निर्यात करना चाहता हूं, जहां शहर 'टोक्यो' के बराबर है (मान लें कि शहर के आंकड़े सभी निचले हैं)।

यह कैसे करना है?

इससे कोई फर्क नहीं पड़ता कि समाधान फ्रीवेयर GUI उपकरण या कमांड लाइन में है (हालांकि GUI उपकरण समाधान बेहतर है)। मैंने pgAdmin III की कोशिश की थी, लेकिन मुझे ऐसा करने का विकल्प नहीं मिला।


2
आप INSERT कथनों को छोड़ सकते हैं और डेटाबेस के बीच सीधे SELECT का उपयोग करके कॉपी कर सकते हैं। albertech.blogspot.com/2016/11/…
jar

PostgreSQL डेटाबेस में चयन नहीं कर सकता है। कम से कम, पुराने संस्करण और न ही ग्रीनप्लम कर सकते हैं, 9.x के बारे में नहीं जानते।
फिलिहब्स

मुझे लगता है इस वर्ष है, लेकिन मैं सिर्फ इतना है कि यह उल्लेख करना चाहता था है का उपयोग कर डेटाबेस भर में चयन करने के लिए संभव dblink है, जो के बाद से कम से कम v8.3 उपलब्ध किया गया है। यह "रिमोट" डेटाबेस से कनेक्ट करने के लिए विदेशी सर्वर और विदेशी डेटा रैपर का उपयोग करता है। यह काम करता है कि क्या वे डेटाबेस एक ही उदाहरण या पूरी तरह से अलग होस्ट पर मौजूद हैं। मैंने कुछ रिपोर्टिंग की सुविधा के लिए अन्य डेटाबेस में भौतिक विचारों को बनाने के लिए इसका काफी उपयोग किया है और यह बहुत अच्छा काम करता है।
G_Hosa_Phat

जवाबों:


282

उस सेट के साथ एक तालिका बनाएं जिसे आप निर्यात करना चाहते हैं और फिर कमांड लाइन उपयोगिता 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 उपकरण समाधान नहीं दे सकता है, तो आपका उत्तर स्वीकार कर लिया जाएगा
null

2
बस अन्य लोगों को साझा करना चाहते हैं, आप इस मुफ्त GUI टूल का उपयोग भी कर सकते हैं: SQL कार्यक्षेत्र / J (पोस्टग्रेएसक्यूएल jdbc4 ड्राइवर के साथ), वही काम करने के लिए।
null

2
यह बहुत से बेहतर होगा create view export_view..., क्योंकि दृश्य आधार तालिका में परिवर्तन के साथ करने की तारीख रहेगा। डॉक्स कहते हैं --table=table: Dump only tables (or **views**...तो मैं कुछ उम्मीद है कि यह काम होता था, लेकिन एक दृश्य के डंपिंग उदासी कोई डेटा अर्जित करता है। : पी
poshest

1
@poshest यह मेरे लिए 9.5 में काम करता है। आपने वास्तव में क्या प्रयास किया?
क्लोडोल्डो नेटो

@ClodoaldoNeto ओह, ठीक है महान! मुझे उम्मीद है कि मैं भी काम कर पाऊंगा। मैंने इस्तेमाल किया pg_dump --table=my_schema.my_view --data-only --inserts my_db > data.sql, संस्करण 9.5.3, और मेरा createबयान केवल आपके अलावा जैसा था create view...। आउटपुट में मुझे प्राप्त होने वाली सभी सामान्य टिप्पणियां और SETकथन हैं। यकीन नहीं होता कि मैं कहां गलत हूं।
poshest

176

एक के लिए केवल डेटा निर्यात उपयोग 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_dumppsql

\copyPsql का आदेश भी है कि:

एक फ्रंटएंड (क्लाइंट) कॉपी करता है। यह एक ऑपरेशन है जो एक SQL COPYकमांड चलाता है , लेकिन निर्दिष्ट फ़ाइल को पढ़ने या लिखने के बजाय, psql फ़ाइल को पढ़ता है या लिखता है और सर्वर और स्थानीय फ़ाइल सिस्टम के बीच डेटा को रूट करता है। इसका मतलब यह है कि फ़ाइल पहुंच और विशेषाधिकार स्थानीय उपयोगकर्ता के हैं, सर्वर के नहीं, और एसक्यूएल सुपरसुसर विशेषाधिकारों की आवश्यकता नहीं है।


10
ओपी विशेष रूप से एसक्यूएल स्क्रिप्ट फ़ाइल डालने के रूप में डेटा के लिए कहता है । मुझे लगता है कि वह insertआज्ञाओं के बारे में बात कर रहा है , क्या तुम नहीं?
क्लोडाल्डो नेटो

1
@ क्लोडोल्डो: आप सही हो सकते हैं, इस मामले में आपका जवाब बेहतर होगा। कोई pgAdmin में क्रिएट स्क्रिप्ट को अलग से कॉपी कर सकता है (जैसा कि ओपी GUIs का उल्लेख करता है)।
इरविन ब्रान्डेसटेटर

3
STDINऔर STDOUTछोटे डेटा निर्यात के लिए उपयोगी, फ़ाइल पथ के स्थान पर उपयोग किया जा सकता है।
अमीर अली अकबरी

1
बिना--column-inserts झंडा, pg_dump एक का उपयोग करता है COPYSQL कोड उत्पन्न में तालिकाओं से प्रत्येक के लिए stdin से।
रान्डेल

2
ध्यान रखें कि आपके द्वारा चयनित स्तंभों का क्रम गंतव्य डेटाबेस में स्तंभों के क्रम से मेल खाता है। यदि ऐसा नहीं होता है, तो यह विफल हो सकता है, या इससे भी बदतर, सफल हो सकता है, लेकिन खराब डेटा सम्मिलित कर सकता है।
नाथन वालेस

32

यह अतिरिक्त स्थापना के बिना मैन्युअल रूप से pgAdmin के साथ एक स्क्रिप्ट में तालिका निर्यात करने का एक आसान और तेज़ तरीका है :

  1. लक्ष्य तालिका पर राइट क्लिक करें और "बैकअप" चुनें।
  2. बैकअप स्टोर करने के लिए एक फ़ाइल पथ का चयन करें। प्रारूप "सादा" चुनें।
  3. नीचे "डंप विकल्प # 2" टैब खोलें और "कॉलम कॉलम का उपयोग करें" जांचें।
  4. बैकअप-बटन पर क्लिक करें।
  5. यदि आप परिणामी फ़ाइल को एक पाठ रीडर (जैसे नोटपैड ++) के साथ खोलते हैं, तो आपको पूरी तालिका बनाने के लिए एक स्क्रिप्ट मिलती है। वहां से आप जनरेट किए गए INSERT-स्टेटमेंट्स को कॉपी कर सकते हैं।

यह तरीका @Clodoaldo Neto के उत्तर में दिखाए गए अनुसार Export_table बनाने की तकनीक के साथ भी काम करता है।

लक्ष्य तालिका पर दाईं ओर क्लिक करें और "बैकअप" चुनें

एक गंतव्य पथ चुनें और प्रारूप को "सादा" में बदलें

नीचे "डंप विकल्प # 2" टैब खोलें और "कॉलम कॉलम का उपयोग करें" जांचें।

आप INSERT स्टेटमेंट को वहां से कॉपी कर सकते हैं।


जब मैं ऐसा करता हूं, तो "बक्कुप" विकल्प नहीं है। यह pgAdmin III v1.18.1 Greenplum 4.3.4.1 (PostgreSQL 8.2.15 पर आधारित) से जुड़ रहा है।
फिलिहब्स

मैं pgAdmin तृतीय v1.18.1 स्थापित किया है और वहाँ था "बैकअप" विकल्प। मैं एक PostgreSQL 9.5 से जुड़ा। तो समस्या सबसे ज्यादा शायद pgAdmin और Greenplum के बीच है।
एंडी आर

काम करता है के रूप में pgAdmin4
निखिल

9

SQL कार्यक्षेत्र में ऐसी सुविधा है।

क्वेरी चलाने के बाद, क्वेरी परिणामों पर राइट क्लिक करें और "कॉपी डेटा अस SQL> SQL इंसर्ट" चुनें।


1
यह बहुत अच्छा काम करता है। जब आप 'पोस्टग्रेज' को 'ड्राइवर' के रूप में चुनते हैं, तो यह संभव है कि आपको स्वयं JDBC ड्राइवरों को डाउनलोड करना होगा: jdbc.postgresql.org/download.html (यह एक .jar फ़ाइल - जावा बाइनरी) है और इसे इस प्रकार जोड़ें। Postgresql पारखी का 'ड्राइवर'। कनेक्शन स्ट्रिंग (या इंटरफ़ेस में URL) इस तरह दिखना चाहिए: jdbc: postgresql: //127.0.0.1: 5432 / db_name
mrmuggles

DBVisualizer में एक समान और उत्कृष्ट विशेषता होती है जो किसी फ़ाइल या क्लिपबोर्ड पर सीधे कॉपी कर सकती है।
नौमेनन

8

मेरे उपयोग के मामले के लिए मैं बस grep करने में सक्षम था।

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

2
दूसरे क्षेत्र में 'टोको' होने के बारे में विचार करना चाहिए।
बायोकट जोको रिवई

@BuyutJokoRivai के बाद से यह एक मेज है केवल ज्यादातर मामलों में यह ठीक होना चाहिए में डंप
इस्माइल इकबाल

इस मामले पर दूसरों के बीच सबसे चालाक तरीका <3
नाम जी वीयू

हालांकि बड़ी तालिका के साथ, आप grep के लिए सभी पंक्तियों को डंप करेंगे जो आपके समाधान के लिए नुकसान का मामला है। फिर, जिस तरह से हम एक तालिका में परिणाम के रूप में डंप करने के लिए क्वेरी और स्टोर करते हैं, वैसे ही यहां stackoverflow.com/a/12816187/248616 अधिक उपयुक्त है
Nam 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');

मिश्रित पोस्ट डेटेटाइप (टेक्स्ट, डबल, इंट, टाइमस्टैम्प विदाउट ज़ोन, आदि) के साथ एक तालिका के साथ, मेरे पोस्टगर्ल्स 9.1 पर परीक्षण किया गया।

इसीलिए TEXT टाइप में CAST की जरूरत है। मेरा परीक्षण लगभग 9M लाइनों के लिए सही ढंग से चलता है, ऐसा लगता है कि यह चलने के 18 मिनट पहले ही विफल हो गया।

ps: मुझे WEB पर mysql के लिए एक समान मिला।


3

आप निर्दिष्ट रिकॉर्ड के साथ तालिका का दृश्य बना सकते हैं और फिर sql फ़ाइल को डंप कर सकते हैं

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

3
मैंने इसे pgAdmin III में आज़माया, लेकिन व्यू ऑब्जेक्ट के लिए, डंपिंग के लिए कोई विकल्प नहीं है।
नल

नौसिखिया प्रयास करें। मैं इसका उपयोग कर रहा हूं और इसमें निर्यात sql स्क्रिप्ट विकल्प है
Giorgi Peikrishvili

@Giorgi: क्या फ्रीवेयर संस्करण है?
नल

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()

मैंने इसे इंजेक्शन के हमलों के खिलाफ परीक्षण नहीं किया है, कृपया मुझे बताएं कि क्या बोली_लिटरल कॉल उसके लिए पर्याप्त नहीं है।

इसके अलावा यह केवल उन स्तंभों के लिए काम करता है जिन्हें बस :: पाठ और फिर से वापस किया जा सकता है।

इसके अलावा यह ग्रीनप्लम के लिए है, लेकिन मैं एक कारण के बारे में नहीं सोच सकता कि यह पोस्टग्रेज, सीएमआईडब्ल्यूडब्ल्यू पर काम क्यों नहीं करेगा।


-2

" EXECUTE QUERY WRITE RESULT TO FILE " विकल्प के साथ क्वेरी निष्पादित करने वाले pgadmin में u की कोशिश की है

इसका केवल डेटा निर्यात करें, अन्य प्रयास करें

pg_dump -t view_name DB_name > db.sql

-t विकल्प ==> डंप केवल टेबल (या विचार या अनुक्रम) मिलान तालिका को देखें , देखें


1
यह केवल एक create viewबयान का निर्यात करेगा
cdmckay
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.