Получение инструкций по созданию временных таблиц из PostgreSQL


В PostgreSQL вы можете очень легко создать временную таблицу с помощью:

CREATE TEMPORARY TABLE tmp_foo AS
SELECT bar, baz FROM some_table WHERE ...;

Есть ли простой способ получить инструкцию create для этой таблицы? Я могу делать запросы, чтобы получить информацию о структуре таблицы (например, в psql я могу использовать d), но это не дает мне оператор creation, который я могу использовать.

Мне бы хотелось, чтобы я мог материализовать запросы в одной базе данных PostgreSQL, получить структуру таблицы запроса, создать эту временную таблицу в другой, а затем использовать COPY команды для копирования данных из одного в другой, прежде чем продолжить.

2 2

2 ответа:

В общем, восстановление оператора CREATE TABLE становится довольно сложным, если вам нужно учитывать значения по умолчанию столбцов, внешние ключи, ограничения проверки и т. д.

Но продукт утверждения CREATE TABLE AS ... не будет иметь ничего из этого, поэтому он относительно прост. Вставьте имя таблицы в предложение WHERE этого запроса:
SELECT
  format(
    'CREATE TEMP TABLE %s (%s)',
    attrelid::regclass,
    string_agg(
      format(
        '%I %s',
        attname,
        format_type(atttypid, atttypmod)
      ),
      ','
      ORDER BY attnum
    )
  )
FROM pg_attribute
WHERE
  attrelid = 'tmp_foo'::regclass AND
  attnum > 0 AND
  NOT attisdropped
GROUP BY attrelid

В качестве примечания, вместо того, чтобы делать это:

CREATE TEMP TABLE tmp_foo AS SELECT ... ;
COPY tmp_foo TO STDOUT;

... вы можете получить структуру результата SELECT без его фактического запуска, который избегает создания промежуточной копии данных:

CREATE TEMP TABLE tmp_foo AS SELECT ... WITH NO DATA;
COPY (SELECT ...) TO STDOUT;

Проще всего было бы использовать pg_dump:

$ pg_dump -s -t tmp_foo _dbname_

Конечно, это будет работать только для нестационарной таблицы. Но вы также можете просто создать обычную таблицу и сделать канал, КАК pg_dump ... | psql ... или pg_dump ... | pg_restore ..., чтобы выполнить свою задачу.