PostgreSQL tablosundaki belirli satırları INSERT SQL komut dosyası olarak dışa aktarma


196

Adında bir veritabanı şeması nyummyve adında bir tablo var 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)
);

cimoryTablonun verilerini SQL komut dosyası ekle olarak vermek istiyorum . Ancak, sadece şehrin 'tokyo' ya eşit olduğu kayıtları / verileri vermek istiyorum (şehir verilerinin hepsinin küçük harf olduğunu varsayalım).

Nasıl yapılır?

Çözümün ücretsiz GUI araçlarında mı yoksa komut satırında mı olduğu önemli değildir (GUI araçları çözümü daha iyi olsa da). PgAdmin III'ü denemiştim, ancak bunu yapmak için bir seçenek bulamıyorum.


2
INSERT deyimlerini atlayabilir ve doğrudan veritabanları arasında SELECT kullanarak kopyalayabilirsiniz. albertech.blogspot.com/2016/11/…
kavanoz

PostgreSQL veritabanları arasında seçim yapamaz. En azından, eski sürümler Greenplum'u yapamaz ve yapamaz, 9.x'i bilmiyor.
PhilHibbs

Bu eski olduğunun farkındayım, ama ben sadece hatırlatmak istedik olduğu kullanarak veritabanları arasında seçmek mümkün dbLink en azından v8.3 beri mevcut olmuştur. "Uzak" veritabanlarına bağlanmak için yabancı sunucuları ve yabancı veri paketleyicilerini kullanır. Bu, bu veritabanlarının aynı örnekte mi yoksa tamamen farklı ana bilgisayarlarda var olup olmadığına bakar. Belirli raporlamayı kolaylaştırmak için diğer veritabanlarına materyalize görünümler oluşturmak için oldukça yaygın olarak kullandım ve harika çalışıyor.
G_Hosa_Phat

Yanıtlar:


282

Dışa aktarmak istediğiniz kümeyle bir tablo oluşturun ve bir dosyaya vermek için pg_dump komut satırı yardımcı programını kullanın:

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 sütun adlarıyla ekleme komutları olarak dökülecektir.

--data-only şemayı dökmeyin.

Aşağıda yorumlandığı gibi, tablo yerine bir görünüm oluşturmak, yeni bir dışa aktarma gerektiğinde tablo oluşturmayı engelleyecektir.


3
Tamam, şimdiye kadar çözümünüz çalışıyor. Bir şey cevapsız "-U kullanıcı_adı" eklemeniz gerekir. Ayrıca neredeyse ToraSQL aracı ile başarılı, sadece komut dosyası sonuç tarih verilerinde hata var. Hiçbiri 2 gün içinde GUI aracı çözümü veremezse, cevabınız kabul edilecektir
null

2
Sadece diğer insanlarla paylaşmak istiyorum, aynı şeyi yapmak için bu ücretsiz GUI aracını da kullanabilirsiniz: SQL Workbench / J (postgreSQL jdbc4 sürücüsü ile).
null

2
create view export_view...Görünüm, temel tablodaki değişikliklerle güncel kalacağından, bu çok daha iyi olurdu. Dokümanlar söylemek --table=table: Dump only tables (or **views**...İşe yarayacağını umut vardı, ama bir görünüm damping ne yazık ki hiçbir veri verir böylece. : P
poshest

1
@poshest 9.5'te benim için çalışıyor. Tam olarak ne denedin?
Clodoaldo Neto

@ClodoaldoNeto oh, tamam harika! Umarım çalıştırabilirim. pg_dump --table=my_schema.my_view --data-only --inserts my_db > data.sql9.5.3 sürümünü kullandım ve ifadem createsizinkiyle aynıydı create view.... Ben çıktı almak tüm olağan pg_dump yorum ve SETifadeler olduğunu. Nerede yanlış yaptığımdan emin değilim.
poshest

176

Bir İçin yalnızca veri ihracat kullanımı COPY.
Satır başına bir tablo satırı düz metin olarak ( INSERTkomutlar değil ) bir dosya alırsınız , daha küçük ve daha hızlıdır:

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

İçe ile aynı yapı her yerde başka bir tabloya aynı:

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

COPYyazıyor ve okunan dosyalar sunucuya yerel gibi istemci programlarının aksine, pg_dumpveya psqlokuma ve yazma dosyaları müşteriye yerel . Her ikisi de aynı makinede çalışıyorsa, çok önemli değil, ancak uzak bağlantılar için de geçerli.

Ayrıca \copypsql komutu vardır:

Bir ön uç (istemci) kopyası gerçekleştirir. Bu bir SQL COPYkomutu çalıştıran bir işlemdir , ancak sunucu belirtilen dosyayı okuyup yazmak yerine psql dosyayı okur veya yazar ve verileri sunucu ile yerel dosya sistemi arasında yönlendirir. Bu, dosya erişilebilirliği ve ayrıcalıklarının sunucunun değil yerel kullanıcınınki olduğu ve SQL süper kullanıcı ayrıcalıklarının gerekli olmadığı anlamına gelir.


10
OP özellikle sql script dosyası ekle olarak veri çağırır . Sanırım insertkomutlardan bahsediyor , değil mi?
Clodoaldo Neto

1
@Clodoaldo: Haklı olabilirsiniz, bu durumda cevabınız daha uygun olacaktır. Ayrıca pgAdmin'de CREATE komut dosyasını ayrı olarak kopyalayabilirsiniz (OP GUI'lerden bahsedildiği gibi).
Erwin Brandstetter

3
STDINve STDOUTküçük veri dışa aktarmaları için yararlı olan dosya yolu yerine kullanılabilir.
Amir Ali Akbari

1
Olmadan--column-inserts bayrak pg_dump bir kullanır COPYÜrettiği SQL kodunu her tablo için STDIN'den.
Randall

2
SEÇİLEN sütunların sırasının, hedef veritabanındaki sütunların sırasıyla eşleşmesine dikkat edin. Başlamazsa, bu başarısız olabilir veya daha da kötüsü başarılı olabilir, ancak kötü veriler ekleyebilir.
Nathan Wallace

32

Bu, bir tabloyu ek kurulumlar olmadan manuel olarak pgAdmin ile bir komut dosyasına aktarmanın kolay ve hızlı bir yoludur :

  1. Hedef tabloya sağ tıklayın ve "Yedekle" yi seçin.
  2. Yedeklemeyi saklamak için bir dosya yolu seçin. Biçim olarak "Düz" ü seçin.
  3. Alttaki "Döküm Seçenekleri # 2" sekmesini açın ve "Sütun Eklerini Kullan" ı işaretleyin.
  4. Yedekle düğmesini tıklayın.
  5. Ortaya çıkan dosyayı bir metin okuyucu ile açarsanız (örn. Notepad ++) tüm tabloyu oluşturmak için bir komut dosyası alırsınız. Buradan oluşturulan INSERT-Deyimlerini kopyalayabilirsiniz.

Bu yöntem aynı zamanda @Clodoaldo Neto'nun cevabında gösterildiği gibi bir export_table yapma tekniği ile de çalışır.

Hedef tabloya sağ tıklayın ve "Yedekle" yi seçin

Bir hedef yol seçin ve formatı "Düz" olarak değiştirin

Alttaki "Döküm Seçenekleri # 2" sekmesini açın ve "Sütun Eklerini Kullan" ı işaretleyin

INSERT İfadelerini oradan kopyalayabilirsiniz.


Bunu yaptığımda, "Bakckup" seçeneği yok. Bu Greenplum 4.3.4.1'e bağlanan pgAdmin III v1.18.1'dir (PostgreSQL 8.2.15 tabanlı).
PhilHibbs

Ben pgAdmin III v1.18.1 yüklenmiş ve orada oldu "yedek" seçeneği. PostgreSQL 9.5'e bağlandım. Dolayısıyla sorun büyük olasılıkla pgAdmin ve Greenplum arasındadır.
Andi R

PgAdmin4
Nikhil

9

SQL Workbench böyle bir özelliğe sahiptir.

Bir sorguyu çalıştırdıktan sonra, sorgu sonuçlarını sağ tıklayın ve "Verileri SQL Olarak Kopyala> SQL Ekle" yi seçin


1
Harika çalışıyor. 'Sürücü' olarak 'postgres'i seçtiğinizde, JDBC sürücülerini kendiniz indirmeniz gerekebilir : jdbc.postgresql.org/download.html (bu bir .jar dosyası - java ikili) ve postgresql bağlantısının 'sürücüsü'. Bağlantı dizesi (veya arabirimdeki gibi URL) şöyle görünmelidir: jdbc: postgresql: //127.0.0.1: 5432 / db_name
mrmuggles

DBVisualizer , bir dosyaya veya doğrudan panoya kopyalayabilen benzer ve mükemmel bir özelliğe sahiptir.
Noumenon

8

Benim kullanım durumum için basitçe grep için boru başardı.

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

2
Biri diğer alanda 'tokyo' almayı düşünmelidir.
Buyut Joko Rivai

@BuyutJokoRivai bir tablo sadece çoğu durumda dökümü olduğundan iyi olmalı
Ismail Iqbal

Davadaki diğerleri arasında en akıllı yol <3
Nam G VU

Büyük bir tabloya rağmen, çözümünüz için bir tuzak durumda olan grep için tüm satırları dökeceksiniz. Daha sonra, burada sorgulamak için sonucu bir tabloya sorgulama ve saklama şeklimiz stackoverflow.com/a/12816187/248616 daha uygun
Nam G VU

5

@PhilHibbs kodlarına dayanarak bunu yapan bir prosedür yazmaya çalıştım. Lütfen bir göz atın ve test edin.

 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;

Ve sonra :

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

karışık alan veri tipine sahip bir tabloyla (metin, çift, int, saat dilimi olmadan zaman damgası, vb.) Postgres 9.1imde test edildi.

Bu nedenle METİN türündeki CAST gereklidir. Testim yaklaşık 9M hatları için doğru çalışıyor, 18 dakika koşmadan hemen önce başarısız gibi görünüyor.

ps: WEB üzerinde mysql için bir eşdeğer buldum.


3

Belirtilen kayıtları içeren tabloyu görüntüleyebilir ve daha sonra sql dosyasını dökebilirsiniz

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

3
PgAdmin III'te denedim, ancak View nesnesi için damping için seçenek yok.
boş

Navicat'ı dene. Ben kullanıyorum ve ihracat sql script seçeneği var
Giorgi Peikrishvili

@Giorgi: Ücretsiz bir sürümü var mı?
null

Postgres 9.1
HCarrasko

2

Bunu yapmak için hızlı bir prosedür çaldım. Yalnızca tek bir satır için çalışır, bu yüzden sadece istediğim satırı seçen geçici bir görünüm oluştururum ve sonra pg_temp.temp_view'ı eklemek istediğim gerçek tabloyla değiştiririm.

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;

Böylece çağrıldı:

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

Bunu enjeksiyon saldırılarına karşı test etmedim, lütfen quote_literal çağrısı bunun için yeterli olup olmadığını bize bildirin.

Ayrıca, yalnızca :: text'e ve tekrar geri çevrilebilen sütunlar için de çalışır.

Ayrıca bu Greenplum için ama Postgres, CMIIW üzerinde çalışmamasının bir nedenini düşünemiyorum.


-2

u " EXECUTE QUERY WRITE RESULT TO FILE " seçeneği ile sorguyu yürütme pgadmin denediniz mi

bu sadece verileri dışa aktarır, yoksa şunu deneyin

pg_dump -t view_name DB_name > db.sql

-t seçeneği ==> Yalnızca eşleşen tabloları (veya görünümleri veya sıraları) eşleşen tabloyu dök, bkz.


1
Bu sadece bir create viewbildirimi dışa
aktarır
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.