วิธีการสร้างคำสั่ง "สร้างตาราง" sql สำหรับตารางที่มีอยู่ใน postgreSQL


250

ฉันสร้างตารางใน postgreSQL แล้ว ฉันต้องการดูคำสั่ง SQL ที่ใช้สร้างตาราง แต่ไม่สามารถคิดออกได้

ฉันจะรับคำcreate tableสั่ง SQL สำหรับตารางที่มีอยู่ใน Postgres ผ่าน commandline หรือคำสั่ง SQL ได้อย่างไร

คำตอบ:


360
pg_dump -t 'schema-name.table-name' --schema-only database-name

ข้อมูลเพิ่มเติม - ในคู่มือ


53
ฉันต้องระบุฐานข้อมูลด้วย pg_dump mydb -t mytable --schema-only.
Nic

1
@Milen A. Radev: โปรดแก้ไขคำตอบเพื่อรวม dbname ฉันใช้เวลา 5 นาทีในการทดลองรูปแบบของไวยากรณ์ที่ผ่านการรับรอง (เนื่องจากฉันไม่ได้ใช้ฐานข้อมูลเริ่มต้น) ขอบคุณ!
farthVader

1
ฉันไม่สามารถทำให้มันใช้งานได้ ปิดแผลดาวน์โหลด pgAdminIII และใช้เครื่องมือของพวกเขาในการสร้างโชว์ให้ฉันดู ฉันประหลาดใจ postgres ไม่มีฟังก์ชันนี้โดยไม่จำเป็นต้องทำการถ่ายโอนข้อมูล
Amalgovinus

5
แทนที่aschemaด้วยชื่อสกีมาจริงของตารางที่คุณต้องการดัมพ์ แทนที่atableด้วยชื่อตารางจริงของตารางที่คุณต้องการดัมพ์
steveha

6
วิธีนี้ใช้งานได้ แต่ถ้าชื่อตารางมีตัวอักษรตัวใหญ่ตัวใดตัวหนึ่งอยู่คุณต้องใส่ชื่อตารางด้วยเครื่องหมายคำพูดเดี่ยวและคู่: pg_dump mydb -t '"TableName"' --schema-only- มิฉะนั้น pg_dump จะไม่รู้จักชื่อตาราง
Josh

81

โซลูชันของฉันคือการล็อกอินเข้าสู่ postgres db โดยใช้ psql ด้วยตัวเลือก -E ดังนี้:

psql -E -U username -d database   

ใน psql ให้รันคำสั่งต่อไปนี้เพื่อดู sql ที่ postgres ใช้เพื่อสร้าง
คำสั่งอธิบายตาราง:

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

ตาม sql echoed out หลังจากรันคำสั่งอธิบายเหล่านี้ฉันสามารถรวบรวม
ฟังก์ชัน plpgsql ต่อไปนี้:

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;

นี่คือฟังก์ชั่นการใช้งาน:

SELECT generate_create_table_statement('tablename');

และนี่คือคำสั่งดรอปหากคุณไม่ต้องการให้ฟังก์ชันนี้คงอยู่อย่างถาวร:

DROP FUNCTION generate_create_table_statement(p_table_name varchar);

2
ดีฉันกำลังมองหาวิธี plpgsql ส่วน LOOP เสียไปเล็กน้อยมันสร้างคอลัมน์แรกสองครั้งและข้ามคอลัมน์สุดท้าย ฉันได้แก้ไขโพสต์เพื่อแก้ไขปัญหานี้
Webmut

มีประโยชน์มากเช่นนี้ยังช่วยให้คุณสร้างคำสั่งตารางสำหรับมุมมอง :)
Wolph

"อิงจาก sql echoed out หลังจากรันคำสั่งเหล่านี้อธิบาย" - ฉันไม่เห็นเอาต์พุต sql ใด ๆ ตัวอธิบายคอลัมน์เท่านั้น ฉันพลาดอะไรไปรึเปล่า?
ekkis

การใช้ generate_create_table_statement ('my_table') จะทำให้ประเภทอาร์กิวเมนต์ไม่ตรงกัน การใช้ generate_create_table_statement (my_table) โดยไม่มีผลลัพธ์เครื่องหมายคำพูดใน 'คอลัมน์ "my_table" Guess เป็นปัญหาที่ขึ้นกับรุ่น psql ความคิดใด ๆ
Jason Morgan

น่าเสียดายที่ฟังก์ชั่นนี้ให้ผลตอบแทนNULLแก่ฉันเท่านั้น... และสคีมานั้นจัดการอย่างไร มันควรส่งคืนคำสั่ง CREATE สำหรับตารางที่มีชื่อที่ระบุจากสกีมาทั้งหมดหรือไม่
Matthias Samsel

39

สร้างคำสั่งสร้างตารางสำหรับตารางใน postgresql จาก command line linux:

คำสั่งนี้ส่งออกตารางสร้างคำสั่ง sql สำหรับฉัน:

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

คำอธิบาย:

pg_dump ช่วยให้เรารับข้อมูลเกี่ยวกับฐานข้อมูลเอง -Uย่อมาจากชื่อผู้ใช้ ผู้ใช้ pgadmin ของฉันไม่มีการตั้งรหัสผ่านดังนั้นฉันไม่จำเป็นต้องใส่รหัสผ่าน -tตัวเลือกวิธีการระบุสำหรับตารางหนึ่ง --schema-onlyหมายถึงพิมพ์เฉพาะข้อมูลเกี่ยวกับตารางไม่ใช่ข้อมูลในตาราง นี่คือคำสั่งที่แน่นอนที่ฉันใช้:

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

27

หากคุณต้องการค้นหาคำสั่งสร้างสำหรับตารางโดยไม่ใช้ pg_dump แบบสอบถามนี้อาจใช้งานได้สำหรับคุณ (เปลี่ยน 'tablename' ด้วยสิ่งที่เรียกว่าตารางของคุณ):

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;

เมื่อเรียกใช้โดยตรงจาก psql จะเป็นประโยชน์ต่อการทำ:

\pset linestyle old-ascii

นอกจากนี้ฟังก์ชันgenerate_create_table_statementในเธรดนี้ทำงานได้ดีมาก


เพิ่งอยากรู้อยากเห็นทำไมคุณต้องการทำเช่นนี้แทนที่จะใช้ pg_dump?
Christopher Reid

7
สวัสดี usecase ของฉันคือฉันมีสิทธิ์เข้าถึงฐานข้อมูล แต่ไม่ใช่เชลล์ การรัน pg_dump ต้องการให้คุณมีผู้ใช้ระบบ
shekwi

ใช่ แต่นี้ไม่ได้ผลิตสิทธิ์และข้อ จำกัด pg_dumpที่ผมเห็นในตอนท้ายของ มีประโยชน์เหมือนกันทุก +1
ekkis

1
รหัสที่ยอดเยี่ยมโดยเฉพาะอย่างยิ่งพวกเราที่มาจาก MySQL โดยใช้ SHOW CREATE TABLE table_name นอกจากนี้ฉันกำลังเข้าถึงฐานข้อมูลที่มีสิทธิ์ จำกัด ดังนั้นนี่จึงสมบูรณ์แบบ
Eric P

1
ดี แต่ไม่รวมค่าเริ่มต้น
dland

17

Dean Toaderยอดเยี่ยมมาก! ฉันจะแก้ไขโค้ดของคุณเล็กน้อยเพื่อแสดงข้อ จำกัด ทั้งหมดในตารางและเพื่อให้สามารถใช้รูปแบบ regexp ในชื่อตารางได้

CREATE OR REPLACE FUNCTION public.generate_create_table_statement(p_table_name character varying)
  RETURNS SETOF text AS
$BODY$
DECLARE
    v_table_ddl   text;
    column_record record;
    table_rec record;
    constraint_rec record;
    firstrec boolean;
BEGIN
    FOR table_rec IN
        SELECT c.relname FROM pg_catalog.pg_class c
            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                WHERE relkind = 'r'
                AND relname~ ('^('||p_table_name||')$')
                AND n.nspname <> 'pg_catalog'
                AND n.nspname <> 'information_schema'
                AND n.nspname !~ '^pg_toast'
                AND pg_catalog.pg_table_is_visible(c.oid)
          ORDER BY c.relname
    LOOP

        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 = table_rec.relname
                    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;

        firstrec := TRUE;
        FOR constraint_rec IN
            SELECT conname, pg_get_constraintdef(c.oid) as constrainddef 
                FROM pg_constraint c 
                    WHERE conrelid=(
                        SELECT attrelid FROM pg_attribute
                        WHERE attrelid = (
                            SELECT oid FROM pg_class WHERE relname = table_rec.relname
                        ) AND attname='tableoid'
                    )
        LOOP
            v_table_ddl:=v_table_ddl||','||chr(10);
            v_table_ddl:=v_table_ddl||'CONSTRAINT '||constraint_rec.conname;
            v_table_ddl:=v_table_ddl||chr(10)||'    '||constraint_rec.constrainddef;
            firstrec := FALSE;
        END LOOP;
        v_table_ddl:=v_table_ddl||');';
        RETURN NEXT v_table_ddl;
    END LOOP;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION public.generate_create_table_statement(character varying)
  OWNER TO postgres;

ตอนนี้คุณสามารถทำแบบสอบถามดังต่อไปนี้

SELECT * FROM generate_create_table_statement('.*');

ซึ่งผลลัพธ์เช่นนี้:

CREATE TABLE public.answer (                                                                        
     id integer DEFAULT nextval('answer_id_seq'::regclass) NOT NULL,                               
     questionid integer  NOT NULL,                                                                  
     title character varying  NOT NULL,                                                             
     defaultvalue character varying  NULL,                                                          
     valuetype integer  NOT NULL,                                                                   
     isdefault boolean  NULL,                                                                       
     minval double precision  NULL,                                                                 
     maxval double precision  NULL,                                                                 
     followminmax integer DEFAULT 0 NOT NULL,                                                       
CONSTRAINT answer_pkey                                                                              
     PRIMARY KEY (id),                                                                              
CONSTRAINT answer_questionid_fkey                                                                  
     FOREIGN KEY (questionid) REFERENCES question(id) ON UPDATE RESTRICT ON DELETE RESTRICT,       
CONSTRAINT answer_valuetype_fkey                                                                   
     FOREIGN KEY (valuetype) REFERENCES answervaluetype(id) ON UPDATE RESTRICT ON DELETE RESTRICT);

สำหรับแต่ละตารางผู้ใช้


2
ใช้งานได้กับตารางที่อยู่ในสคีมาสาธารณะเท่านั้น
แบรดแมทธิวส์

13

วิธีที่ง่ายที่สุดที่ฉันคิดได้คือติดตั้ง pgAdmin 3 (ดูที่นี่ ) และใช้เพื่อดูฐานข้อมูลของคุณ มันจะสร้างแบบสอบถามโดยอัตโนมัติที่จะสร้างตารางในคำถาม


1
pgAdmin ดูดี แต่น่าเสียดายที่ผมไม่ได้มีการเข้าถึงรากในการติดตั้งบนเซิร์ฟเวอร์ ..
ราชา

11
คุณไม่จำเป็นต้องติดตั้งลงบนเซิร์ฟเวอร์ วางไว้บนเดสก์ท็อปของคุณแล้วเชื่อมต่อกับเซิร์ฟเวอร์
Corin

8

หากคุณต้องการทำสิ่งนี้กับตารางต่าง ๆ พร้อมกันคุณต้องใช้ -t สลับหลายครั้ง (ใช้เวลาสักครู่เพื่อหาสาเหตุที่รายการที่คั่นด้วยเครื่องหมายจุลภาคไม่ทำงาน) นอกจากนี้ยังมีประโยชน์ในการส่งผลลัพธ์ไปยัง outfile หรือไพพ์ไปยังเซิร์ฟเวอร์ postgres บนเครื่องอื่น

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

5

ปรับเปลี่ยนได้มากขึ้นตามการตอบสนองจาก @vkkeeper เพิ่มความเป็นไปได้ในการสืบค้นตารางจากสคีมาที่เฉพาะเจาะจง

CREATE OR REPLACE FUNCTION public.describe_table(p_schema_name character varying, p_table_name character varying)
  RETURNS SETOF text AS
$BODY$
DECLARE
    v_table_ddl   text;
    column_record record;
    table_rec record;
    constraint_rec record;
    firstrec boolean;
BEGIN
    FOR table_rec IN
        SELECT c.relname, c.oid FROM pg_catalog.pg_class c
            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                WHERE relkind = 'r'
                AND n.nspname = p_schema_name
                AND relname~ ('^('||p_table_name||')$')
          ORDER BY c.relname
    LOOP
        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.oid = table_rec.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;

        firstrec := TRUE;
        FOR constraint_rec IN
            SELECT conname, pg_get_constraintdef(c.oid) as constrainddef
                FROM pg_constraint c
                    WHERE conrelid=(
                        SELECT attrelid FROM pg_attribute
                        WHERE attrelid = (
                            SELECT oid FROM pg_class WHERE relname = table_rec.relname
                                AND relnamespace = (SELECT ns.oid FROM pg_namespace ns WHERE ns.nspname = p_schema_name)
                        ) AND attname='tableoid'
                    )
        LOOP
            v_table_ddl:=v_table_ddl||','||chr(10);
            v_table_ddl:=v_table_ddl||'CONSTRAINT '||constraint_rec.conname;
            v_table_ddl:=v_table_ddl||chr(10)||'    '||constraint_rec.constrainddef;
            firstrec := FALSE;
        END LOOP;
        v_table_ddl:=v_table_ddl||');';
        RETURN NEXT v_table_ddl;
    END LOOP;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

4

นี่เป็นรุ่นบิตที่ดีขึ้นของshekwi 's แบบสอบถาม
มันสร้างข้อ จำกัด คีย์หลักและสามารถจัดการตารางชั่วคราว:

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;

ใช้table_nameพารามิเตอร์เพื่อระบุชื่อของตาราง


1
รวม PKs แต่ไม่ได้จัดการ DEFAULTs
DKroot

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

3
ในขณะที่ข้อมูลโค้ดนี้อาจแก้ปัญหาได้รวมถึงคำอธิบายช่วยปรับปรุงคุณภาพของโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
DimaSan

2

นี่คือรูปแบบที่เหมาะกับฉัน:

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

นอกจากนี้หากคุณใช้สคีมาคุณจะต้องระบุด้วย:

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

คุณจะได้รับผลลัพธ์ที่คุณสามารถใช้เพื่อสร้างตารางอีกครั้งเพียงแค่เรียกใช้เอาต์พุตใน psql


0

ทางออกที่ง่ายใน SQL เดียวที่บริสุทธิ์ คุณได้รับแนวคิดคุณอาจขยายไปยังคุณลักษณะเพิ่มเติมที่คุณต้องการแสดง

with c as (
SELECT table_name, ordinal_position, 
 column_name|| ' ' || data_type col
, row_number() over (partition by table_name order by ordinal_position asc) rn
, count(*) over (partition by table_name) cnt
FROM information_schema.columns
WHERE table_name   in ('pg_index', 'pg_tables')
order by table_name, ordinal_position
)
select case when rn = 1 then 'create table ' || table_name || '(' else '' end
 || col 
 || case when rn < cnt then ',' else '); ' end
from c 
order by table_name, rn asc;

เอาท์พุท:

create table pg_index(indexrelid oid,
 indrelid oid,
 indnatts smallint,
 indisunique boolean,
 indisprimary boolean,
 indisexclusion boolean,
 indimmediate boolean,
 indisclustered boolean,
 indisvalid boolean,
 indcheckxmin boolean,
 indisready boolean,
 indislive boolean,
 indisreplident boolean,
 indkey ARRAY,
 indcollation ARRAY,
 indclass ARRAY,
 indoption ARRAY,
 indexprs pg_node_tree,
 indpred pg_node_tree);

 create table pg_tables(schemaname name,
 tablename name,
 tableowner name,
 tablespace name,
 hasindexes boolean,
 hasrules boolean,
 hastriggers boolean,
 rowsecurity boolean);

* ไม่ได้จัดการกับตารางที่มีชื่อเดียวกันในหลาย schemas * ไม่รวมความยาวของประเภท
DKroot

0

นี่เป็นคำสั่งเดียวที่จะสร้าง DDL สำหรับตารางเดียวในสคีมาที่ระบุรวมถึงข้อ จำกัด

SELECT 'CREATE TABLE ' || pn.nspname || '.' || pc.relname || E'(\n' ||
   string_agg(pa.attname || ' ' || pg_catalog.format_type(pa.atttypid, pa.atttypmod) || coalesce(' DEFAULT ' || (
                                                                                                               SELECT pg_catalog.pg_get_expr(d.adbin, d.adrelid)
                                                                                                               FROM pg_catalog.pg_attrdef d
                                                                                                               WHERE d.adrelid = pa.attrelid
                                                                                                                 AND d.adnum = pa.attnum
                                                                                                                 AND pa.atthasdef
                                                                                                               ),
                                                                                                 '') || ' ' ||
              CASE pa.attnotnull
                  WHEN TRUE THEN 'NOT NULL'
                  ELSE 'NULL'
              END, E',\n') ||
   coalesce((SELECT E',\n' || string_agg('CONSTRAINT ' || pc1.conname || ' ' || pg_get_constraintdef(pc1.oid), E',\n' ORDER BY pc1.conindid)
            FROM pg_constraint pc1
            WHERE pc1.conrelid = pa.attrelid), '') ||
   E');'
FROM pg_catalog.pg_attribute pa
JOIN pg_catalog.pg_class pc
    ON pc.oid = pa.attrelid
    AND pc.relname = 'table_name'
JOIN pg_catalog.pg_namespace pn
    ON pn.oid = pc.relnamespace
    AND pn.nspname = 'schema_name'
WHERE pa.attnum > 0
    AND NOT pa.attisdropped
GROUP BY pn.nspname, pc.relname, pa.attrelid;

0

เช่นเดียวกับคำตอบอื่น ๆ ที่กล่าวถึงไม่มีฟังก์ชันในตัวที่ทำสิ่งนี้

นี่คือฟังก์ชันที่พยายามรับข้อมูลทั้งหมดที่จำเป็นในการทำซ้ำตาราง - หรือเพื่อเปรียบเทียบการนำไปใช้งานและตรวจสอบใน ddl

ฟังก์ชั่นนี้ส่งออก:

  • คอลัมน์ (ด้วยความแม่นยำ, เป็นโมฆะ / ไม่เป็นโมฆะ, ค่าเริ่มต้น)
  • ข้อ จำกัด
  • ดัชนี

CREATE OR REPLACE FUNCTION public.show_create_table(
  in_schema_name varchar,
  in_table_name varchar
)
RETURNS text
LANGUAGE plpgsql VOLATILE
AS
$$
  DECLARE
    -- the ddl we're building
    v_table_ddl text;

    -- data about the target table
    v_table_oid int;

    -- records for looping
    v_column_record record;
    v_constraint_record record;
    v_index_record record;
  BEGIN
    -- grab the oid of the table; https://www.postgresql.org/docs/8.3/catalog-pg-class.html
    SELECT c.oid INTO v_table_oid
    FROM pg_catalog.pg_class c
    LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
    WHERE 1=1
      AND c.relkind = 'r' -- r = ordinary table; https://www.postgresql.org/docs/9.3/catalog-pg-class.html
      AND c.relname = in_table_name -- the table name
      AND n.nspname = in_schema_name; -- the schema

    -- throw an error if table was not found
    IF (v_table_oid IS NULL) THEN
      RAISE EXCEPTION 'table does not exist';
    END IF;

    -- start the create definition
    v_table_ddl := 'CREATE TABLE ' || in_schema_name || '.' || in_table_name || ' (' || E'\n';

    -- define all of the columns in the table; https://stackoverflow.com/a/8153081/3068233
    FOR v_column_record IN
      SELECT
        c.column_name,
        c.data_type,
        c.character_maximum_length,
        c.is_nullable,
        c.column_default
      FROM information_schema.columns c
      WHERE (table_schema, table_name) = (in_schema_name, in_table_name)
      ORDER BY ordinal_position
    LOOP
      v_table_ddl := v_table_ddl || '  ' -- note: two char spacer to start, to indent the column
        || v_column_record.column_name || ' '
        || v_column_record.data_type || CASE WHEN v_column_record.character_maximum_length IS NOT NULL THEN ('(' || v_column_record.character_maximum_length || ')') ELSE '' END || ' '
        || CASE WHEN v_column_record.is_nullable = 'NO' THEN 'NOT NULL' ELSE 'NULL' END
        || CASE WHEN v_column_record.column_default IS NOT null THEN (' DEFAULT ' || v_column_record.column_default) ELSE '' END
        || ',' || E'\n';
    END LOOP;

    -- define all the constraints in the; https://www.postgresql.org/docs/9.1/catalog-pg-constraint.html && https://dba.stackexchange.com/a/214877/75296
    FOR v_constraint_record IN
      SELECT
        con.conname as constraint_name,
        con.contype as constraint_type,
        CASE
          WHEN con.contype = 'p' THEN 1 -- primary key constraint
          WHEN con.contype = 'u' THEN 2 -- unique constraint
          WHEN con.contype = 'f' THEN 3 -- foreign key constraint
          WHEN con.contype = 'c' THEN 4
          ELSE 5
        END as type_rank,
        pg_get_constraintdef(con.oid) as constraint_definition
      FROM pg_catalog.pg_constraint con
      JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
      JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
      WHERE nsp.nspname = in_schema_name
      AND rel.relname = in_table_name
      ORDER BY type_rank
    LOOP
      v_table_ddl := v_table_ddl || '  ' -- note: two char spacer to start, to indent the column
        || 'CONSTRAINT' || ' '
        || v_constraint_record.constraint_name || ' '
        || v_constraint_record.constraint_definition
        || ',' || E'\n';
    END LOOP;

    -- drop the last comma before ending the create statement
    v_table_ddl = substr(v_table_ddl, 0, length(v_table_ddl) - 1) || E'\n';

    -- end the create definition
    v_table_ddl := v_table_ddl || ');' || E'\n';

    -- suffix create statement with all of the indexes on the table
    FOR v_index_record IN
      SELECT indexdef
      FROM pg_indexes
      WHERE (schemaname, tablename) = (in_schema_name, in_table_name)
    LOOP
      v_table_ddl := v_table_ddl
        || v_index_record.indexdef
        || ';' || E'\n';
    END LOOP;

    -- return the ddl
    RETURN v_table_ddl;
  END;
$$;

ตัวอย่าง

SELECT * FROM public.show_create_table('public', 'example_table');

ผลิต

CREATE TABLE public.example_table (
  id bigint NOT NULL DEFAULT nextval('test_tb_for_show_create_on_id_seq'::regclass),
  name character varying(150) NULL,
  level character varying(50) NULL,
  description text NOT NULL DEFAULT 'hello there!'::text,
  CONSTRAINT test_tb_for_show_create_on_pkey PRIMARY KEY (id),
  CONSTRAINT test_tb_for_show_create_on_level_check CHECK (((level)::text = ANY ((ARRAY['info'::character varying, 'warn'::character varying, 'error'::character varying])::text[])))
);
CREATE UNIQUE INDEX test_tb_for_show_create_on_pkey ON public.test_tb_for_show_create_on USING btree (id);

-1

ในฐานข้อมูล pgadminIII >> schemas >> tables >> คลิกขวาที่ 'Your table' >> สคริปต์ >> 'เลือกอันใดอันหนึ่ง (สร้างแทรกอัปเดตลบ .. )'


-1

นี่คือแบบสอบถามที่มีการแก้ไข

select 'CREATE TABLE ' || a.attrelid::regclass::text || '(' ||
string_agg(a.attname || ' ' || pg_catalog.format_type(a.atttypid, 
a.atttypmod)||
        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
||
        CASE WHEN a.attnotnull = true THEN 
            ' NOT NULL'
        ELSE
            '' END,E'\n,') || ');' 
FROM pg_catalog.pg_attribute a join pg_class on a.attrelid=pg_class.oid
WHERE a.attrelid::regclass::varchar =  
'TABLENAME_with_or_without_schema'
AND a.attnum > 0 AND NOT a.attisdropped  and pg_class.relkind='r'
group by a.attrelid;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.