如何为postgreSQL中的现有表生成“create table”sql语句

我有一个在PostgreSQL中创build的表。 我想看看用于创build表的SQL语句,但无法弄清楚。

如何通过命令行或sql语句获取postgresql中现有表的“create table”sql语句?

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

更多信息 – 在手册中 。

我的解决scheme是使用psql和-E选项login到postgres数据库,如下所示:

 psql -E -U username -d database 

在psql中,运行以下命令来查看postgres用来生成的sql
描述表格声明:

 -- 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,我能够把它们放在一起
下面的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; 

这里是function用法:

 SELECT generate_create_table_statement('tablename'); 

如果你不想让这个函数永久持久化,这里是drop语句:

 DROP FUNCTION generate_create_table_statement(p_table_name varchar); 

从linux命令行中为postgresql中的表生成create table语句:

这个语句为我输出表create sql语句:

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

说明:

pg_dump帮助我们获得关于数据库本身的信息。 -U代表用户名。 我的pgadmin用户没有设置密码,所以我不必input密码。 -t选项意味着指定一个表。 --schema-only表示--schema-only打印关于表格的数据,而不打印表格中的数据。 这是我使用的确切命令:

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

如果你想在没有使用pg_dump的情况下find一个表的create语句,这个查询可能适用于你(不pipe你的表被调用了什么)。

 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工作得很好。

我能想到的最简单的方法是安装pgAdmin 3( 在这里find )并使用它来查看您的数据库。 它会自动生成一个查询来创build有问题的表。

如果你想一次为各种表做这个,你会多次使用-t开关(花了我一些时间来弄清楚为什么逗号分隔列表不工作)。 另外,将结果发送到另一台机器上的输出文件或pipe道到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 

这是适合我的变化:

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

您将得到一个输出,您可以使用它来再次创build表,只需在psql中运行该输出即可。

这里是shekwi 查询的改进版本。
它生成主键约束并能够处理临时表:

 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参数指定表的名称。

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

在pgadminIII数据库>>模式>>表中>>右键点击'你的表'>>脚本>>'select任何一个(创build,插入,更新,删除..)'