Soru PostgreSQL'de varolan bir tablo için "tablo oluştur" sql deyimi nasıl oluşturulur


PostgreSQL'de oluşturulmuş bir tablom var. Tabloyu oluşturmak için kullanılan sql ifadesine bakmak istiyorum ama bunu anlayamıyorum.

Komut satırı veya sql ifadesi aracılığıyla postgresql'de var olan bir tablo için 'create table' sql deyimini nasıl alabilirim?


178
2018-04-07 15:38


Menşei




Cevaplar:


pg_dump -t 'aschema.atable' --schema-only database-name

Daha fazla bilgi Manuel.


257
2018-04-07 17:32



Veritabanını da belirtmek zorundaydım. pg_dump mydb -t mytable --schema-only. - Nic
@Milen A. Radev: Lütfen dbname'yi dahil etmek için cevabı düzenleyin. Bu kalifiye sözdiziminin varyasyonlarını denemek için 5 dakika harcadım (varsayılan db'yi kullanmadığımdan). Teşekkürler! - farthVader
Bunu işe yaramazdım, sadece bir şey çıkarmazdı. PgAdminIII'i indirmeye ve beni bir şov oluşturmak için araçlarını kullanarak yaralayın. Ben sürpriz postgres bir dökümü yapmak gerek kalmadan bu işlevselliğe sahip değilim. - Amalgovinus
değiştirmek aschema dökmek istediğiniz tablonun gerçek şema adı ile. değiştirmek atable dökmek istediğiniz tablonun gerçek tablo adı ile. - steveha
Bu çalışır, ancak tablo adı içinde büyük harf varsa, tablo adını hem tek hem de çift tırnak ile sarmanız gerekir: pg_dump mydb -t '"TableName"' --schema-only - Aksi takdirde pg_dump tablo adını tanımayacaktır. - Josh


Benim çözümüm, aşağıdaki gibi -E seçeneği ile psql kullanarak postgres db giriş yapmaktır:

psql -E -U username -d database   

Psql'de, postgres'in üretmek için kullandığı sql'i görmek için aşağıdaki komutları çalıştırın.
açıklama tablosu deyimi:

-- List all tables in the schema (my example schema name is public)
\dt public.*
-- Choose a table name from above
-- For create table of one public.tablename
\d+ public.tablename  

Bu tanım komutlarını çalıştırdıktan sonra yankılanan sql'e göre, bir araya getirmeyi başardım
aşağıdaki plpgsql işlevi:

CREATE OR REPLACE FUNCTION generate_create_table_statement(p_table_name varchar)
  RETURNS text AS
$BODY$
DECLARE
    v_table_ddl   text;
    column_record record;
BEGIN
    FOR column_record IN 
        SELECT 
            b.nspname as schema_name,
            b.relname as table_name,
            a.attname as column_name,
            pg_catalog.format_type(a.atttypid, a.atttypmod) as column_type,
            CASE WHEN 
                (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
                 FROM pg_catalog.pg_attrdef d
                 WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) IS NOT NULL THEN
                'DEFAULT '|| (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
                              FROM pg_catalog.pg_attrdef d
                              WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)
            ELSE
                ''
            END as column_default_value,
            CASE WHEN a.attnotnull = true THEN 
                'NOT NULL'
            ELSE
                'NULL'
            END as column_not_null,
            a.attnum as attnum,
            e.max_attnum as max_attnum
        FROM 
            pg_catalog.pg_attribute a
            INNER JOIN 
             (SELECT c.oid,
                n.nspname,
                c.relname
              FROM pg_catalog.pg_class c
                   LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
              WHERE c.relname ~ ('^('||p_table_name||')$')
                AND pg_catalog.pg_table_is_visible(c.oid)
              ORDER BY 2, 3) b
            ON a.attrelid = b.oid
            INNER JOIN 
             (SELECT 
                  a.attrelid,
                  max(a.attnum) as max_attnum
              FROM pg_catalog.pg_attribute a
              WHERE a.attnum > 0 
                AND NOT a.attisdropped
              GROUP BY a.attrelid) e
            ON a.attrelid=e.attrelid
        WHERE a.attnum > 0 
          AND NOT a.attisdropped
        ORDER BY a.attnum
    LOOP
        IF column_record.attnum = 1 THEN
            v_table_ddl:='CREATE TABLE '||column_record.schema_name||'.'||column_record.table_name||' (';
        ELSE
            v_table_ddl:=v_table_ddl||',';
        END IF;

        IF column_record.attnum <= column_record.max_attnum THEN
            v_table_ddl:=v_table_ddl||chr(10)||
                     '    '||column_record.column_name||' '||column_record.column_type||' '||column_record.column_default_value||' '||column_record.column_not_null;
        END IF;
    END LOOP;

    v_table_ddl:=v_table_ddl||');';
    RETURN v_table_ddl;
END;
$BODY$
  LANGUAGE 'plpgsql' COST 100.0 SECURITY INVOKER;

İşte işlev kullanımı:

SELECT generate_create_table_statement('tablename');

Ve bu işlevin kalıcı olarak kalmasını istemiyorsanız açılan deyim:

DROP FUNCTION generate_create_table_statement(p_table_name varchar);

62
2018-04-22 18:31



Güzel, plpgsql yolunu arıyordum. LOOP kısmı biraz bozuk olsa da, ilk sütunu iki kez oluşturur ve son sütunu atlar. Bunu düzeltmek için yayını düzenledim. - Webmut
Bu çok yararlı, ayrıca görünümler için bir tablo ifadesi oluşturmanıza olanak sağlar :) - Wolph
Msgstr "Bu komutları çalıştırdıktan sonra sql'e eklenmiş" - Herhangi bir sql çıkışı göremiyorum. sadece sütun tanımlayıcıları. bir şey mi özlüyorum - ekkis
Generate_create_table_statement ('my_table') kullanmak argüman türü uyuşmazlığıyla sonuçlanır. Quote_create_table_statement öğesini (my_table) "sütun" ile sonuçlandırılmadan kullanabiliyorum my_table "mevcut değil. Guess, psql sürümüne bağlı bir sorundur. Herhangi bir fikir? - Jason Morgan
Ne yazık ki, bu işlev sadece döndürür NULL Benim için ... Ve şema nasıl ele alınır? Tüm şemalardan belirtilen ada sahip tablolara CREATE ifadeleri dönmeli mi? - Matthias Samsel


Linux komut satırından postgresql bir tablo için create table deyimini oluşturun:

Bu ifade, tabloyu benim için sql deyimi oluşturuyor:

pg_dump -U your_db_user_name your_database -t your_table_name --schema-only

Açıklama:

pg_dump, veritabanının kendisi hakkında bilgi almamıza yardımcı olur. -U kullanıcı adı anlamına gelir. Pgadmin kullanıcımın şifre seti yok, bu yüzden şifre koymam gerekmiyor. -t seçenek, bir tablo için belirtmek anlamına gelir. --schema-only Tablodaki verileri değil, yalnızca tablo hakkındaki verileri yazdırmak anlamına gelir. İşte benim kullandığım tam komut:

pg_dump -U pgadmin kurz_prod -t fact_stock_info --schema-only

31
2018-04-11 20:36





Bir tablo için create deyimini pg_dump kullanmadan bulmak istiyorsanız, Bu sorgu sizin için işe yarayabilir (tablonuzun adı ne olursa olsun 'tablename' olarak değiştirin):

SELECT                                          
  'CREATE TABLE ' || relname || E'\n(\n' ||
  array_to_string(
    array_agg(
      '    ' || column_name || ' ' ||  type || ' '|| not_null
    )
    , E',\n'
  ) || E'\n);\n'
from
(
  SELECT 
    c.relname, a.attname AS column_name,
    pg_catalog.format_type(a.atttypid, a.atttypmod) as type,
    case 
      when a.attnotnull
    then 'NOT NULL' 
    else 'NULL' 
    END as not_null 
  FROM pg_class c,
   pg_attribute a,
   pg_type t
   WHERE c.relname = 'tablename'
   AND a.attnum > 0
   AND a.attrelid = c.oid
   AND a.atttypid = t.oid
 ORDER BY a.attnum
) as tabledefinition
group by relname;

doğrudan psql'den çağrıldığında, yapmanız gerekenler:

\pset linestyle old-ascii

Ayrıca, işlev generate_create_table_statement Bu iş parçacığında çok iyi çalışıyor.


18
2017-10-01 10:25



Sadece meraktan dolayı, sadece pg_dump kullanmak yerine neden bunu yapmak istersiniz? - AllTheTime
Merhaba. Usecase, veri tabanına erişebildiğim, fakat kabuğu kullanamadığım oldu. Pg_dump'ı çalıştırmak bir sistem kullanıcısına sahip olmanızı gerektirir. - shekwi
evet, ancak bu, sonunda gördüğüm izinleri ve kısıtlamaları üretmiyor. pg_dump. hepsi aynı +1 - ekkis
SHOW CREATE TABLO table_name kullanarak, özellikle MySQL'den gelenler için çok az kod. Ayrıca, sınırlı izinlere sahip bir veritabanına erişiyorum, bu yüzden bu mükemmel. - Eric P


Düşünebildiğim en kolay yöntem pgAdmin 3'ü kurmaktır (burada bulundu) ve veritabanınızı görüntülemek için kullanın. Söz konusu tabloyu oluşturacak bir sorgu otomatik olarak oluşturulur.


10
2018-04-07 15:50



pgAdmin iyi görünüyor, ancak maalesef sunucuya yüklemek için root erişimim yok .. - Raja
Sunucuya yüklemeniz gerekmez. Masaüstünüze koyun ve daha sonra sunucuya bağlayın. - Corin


Bunu bir defada çeşitli tablolar için yapmak isterseniz, -t anahtarını birden çok kez kullanmanız için bana uyardınız (virgülle ayrılmış listenin neden çalışmadığını anlamak için bir süre beni aradınız). Ayrıca, başka bir makinede bir postgres sunucusuna bir outfile veya boru sonuç göndermek için yararlı olabilir

pg_dump -t table1 -t table2 database_name --schema-only > dump.sql

pg_dump -t table1 -t table2 database_name --schema-only | psql -h server_name database_name

7
2018-02-26 08:08





Bu benim için çalışan varyasyon:

pg_dump -U user_viktor -h localhost unit_test_database -t floorplanpreferences_table --schema-only

Ayrıca, şemalar kullanıyorsanız, elbette bunu da belirtmeniz gerekir:

pg_dump -U user_viktor -h localhost unit_test_database -t "949766e0-e81e-11e3-b325-1cc1de32fcb6".floorplanpreferences_table --schema-only

Tabloyu yeniden oluşturmak için kullanabileceğiniz bir çıktı alacaksınız, sadece bu çıkışı psql'de çalıştırın.


2
2017-08-01 00:37





İşte biraz geliştirilmiş sürümü shekwi'ler sorgu.
Ana anahtar kısıtını oluşturur ve geçici tabloları yönetebilir:

with pkey as
(
    select cc.conrelid, format(E',
    constraint %I primary key(%s)', cc.conname,
        string_agg(a.attname, ', ' 
            order by array_position(cc.conkey, a.attnum))) pkey
    from pg_catalog.pg_constraint cc
        join pg_catalog.pg_class c on c.oid = cc.conrelid
        join pg_catalog.pg_attribute a on a.attrelid = cc.conrelid 
            and a.attnum = any(cc.conkey)
    where cc.contype = 'p'
    group by cc.conrelid, cc.conname
)
select format(E'create %stable %s%I\n(\n%s%s\n);\n',
    case c.relpersistence when 't' then 'temporary ' else '' end,
    case c.relpersistence when 't' then '' else n.nspname || '.' end,
    c.relname,
    string_agg(
        format(E'\t%I %s%s',
            a.attname,
            pg_catalog.format_type(a.atttypid, a.atttypmod),
            case when a.attnotnull then ' not null' else '' end
        ), E',\n'
        order by a.attnum
    ),
    (select pkey from pkey where pkey.conrelid = c.oid)) as sql
from pg_catalog.pg_class c
    join pg_catalog.pg_namespace n on n.oid = c.relnamespace
    join pg_catalog.pg_attribute a on a.attrelid = c.oid and a.attnum > 0
    join pg_catalog.pg_type t on a.atttypid = t.oid
where c.relname = :table_name
group by c.oid, c.relname, c.relpersistence, n.nspname;

kullanım table_name tablonun adını belirtmek için parametre.


2
2018-03-12 01:00



PK'leri içerir, ancak DEFAULT'ları işlemez. - DKroot


pg_dump -h XXXXXXXXXXX.us-west-1.rds.amazonaws.com -U anyuser -t tablename -s

2
2018-03-17 20:59



Bu kod pasajı soruyu çözebilirken bir açıklama dahil Gönderinizin kalitesini iyileştirmeye gerçekten yardımcı olur. Gelecekte okuyucular için soruyu cevapladığınızı ve bu kişilerin kod önerilerinizin nedenini bilmeyebileceğini unutmayın. - DimaSan