Как сгенерировать SQL-оператор «создать таблицу» для существующей таблицы в postgreSQL

138

У меня есть таблица, созданная в postgreSQL. Я хочу посмотреть инструкцию sql, используемую для создания таблицы, но не могу понять ее.

Как получить инструкцию sql create table для существующей таблицы в postgresql с помощью команды командной строки или sql?

Теги:

10 ответов

201
Лучший ответ
pg_dump -t 'aschema.atable' --schema-only database-name

Дополнительная информация - в руководстве .

  • 45
    Я должен был указать базу данных тоже. pg_dump mydb -t mytable --schema-only .
  • 1
    @ Милен А. Радев: Пожалуйста, отредактируйте ответ, включив в него имя базы данных. Я потратил 5 минут, чтобы попробовать варианты этого квалифицированного синтаксиса (поскольку я не использовал базу данных по умолчанию). Спасибо!
Показать ещё 5 комментариев
49

Моим решением является вход в 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, отозванного после запуска этих описаний команд, я смог собрать вместе следующую функцию 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, если вы не хотите, чтобы эта функция сохранялась постоянно:

DROP FUNCTION generate_create_table_statement(p_table_name varchar);
  • 1
    Отлично, я искал plpgsql-way. Часть LOOP немного ломаная, она генерирует первый столбец дважды и пропускает последний столбец. Я отредактировал пост, чтобы исправить это.
  • 0
    Очень полезно, поскольку это также позволяет вам создавать оператор таблицы для представлений :)
Показать ещё 3 комментария
31

Создать инструкцию create table для таблицы в postgresql из командной строки linux:

Этот оператор выводит таблицу create sql statement for me:

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
13

Если вы хотите найти инструкцию create для таблицы без использования 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 в этом потоке работает очень хорошо.

  • 0
    Просто из любопытства, почему вы хотите сделать это вместо того, чтобы просто использовать pg_dump?
  • 7
    Привет. Мой вариант использования состоял в том, что я имел доступ к базе данных, но не к оболочке. Запуск pg_dump требует наличия системного пользователя.
Показать ещё 3 комментария
8

Самый простой способ, который я могу придумать, - установить pgAdmin 3 (найденный здесь) и использовать его для просмотра вашей базы данных. Он автоматически сгенерирует запрос, который создаст соответствующую таблицу.

  • 0
    pgAdmin выглядит хорошо, но, к сожалению, у меня нет root-прав для установки на сервер ..
  • 8
    Вам не нужно устанавливать его на сервер. Положите его на рабочий стол, а затем подключите его к серверу.
6

Если вы хотите сделать это для разных таблиц сразу, вам понадобилось несколько раз использовать ключ -t (мне потребовалось некоторое время, чтобы выяснить, почему список, разделенный запятыми, не работает). Кроме того, может быть полезно отправить результаты в outfile или 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
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

В базе данных pgadminIII → схемы → таблицы → щелкните правой кнопкой мыши на "вашей таблице" → скрипты → "Выберите любой (создать, вставить, обновить, удалить..)"

0
pg_dump -h XXXXXXXXXXX.us-west-1.rds.amazonaws.com -U anyuser -t tablename -s
  • 2
    Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код.
0

Вот немного улучшенная версия 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, чтобы указать имя таблицы.

  • 1
    Включает PK, но не обрабатывает DEFAULT.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню