如何创建表... LIKE 没有 NOT NULL 约束?

Ale*_*eto 12 postgresql

我正在尝试使用一些动态 SQL 在函数内重新创建表的结构。

EXECUTE 'CREATE TABLE ' || my_table_name || '_bk' ||
    ' (like ' || _my_table_name || ')';
Run Code Online (Sandbox Code Playgroud)

这将类似于:

CREATE TABLE my_table_bk
(like my_table);
Run Code Online (Sandbox Code Playgroud)

但我需要放弃所有约束。使用EXCLUDING CONSTRAINTS类似的选项,它仍然复制NOT NULL约束(文档证实了这一行为):

CREATE TABLE my_table_bk
(like my_table EXCLUDING CONSTRAINTS);
Run Code Online (Sandbox Code Playgroud)

问题是,如何在没有 NOT NULL 约束的情况下重新创建表结构,或者删除表中的所有 NOT NULL 约束?

小智 19

尝试这个:

CREATE TABLE my_table_bk
AS
  SELECT *
  FROM my_table
  WHERE false;
Run Code Online (Sandbox Code Playgroud)

或者,您可以附加LIMIT 0而不是WHERE子句。

这将创建一个my_table_bkmy_table没有约束和没有数据的结构相同的表。


Vér*_*ace 8

这是在 Stack Overflow 上如何一次性从 PostgreSQL 表中删除所有 NOT NULL 约束中提出的问题。它似乎提供了一系列很好的解决方案。

接受的答案丹尼斯日Bernardy是:

您可以将它们全部分组在同一个 alter 语句中:

   alter table tbl alter col1 drop not null,
                   alter col2 drop not null,
                   …
Run Code Online (Sandbox Code Playgroud)

如果您想编写一个do 块来生成所需的 SQL ,您还可以从目录中检索相关列的列表。例如,类似于:

select a.attname
  from pg_catalog.pg_attribute a
 where attrelid = 'tbl'::regclass
   and a.attnum > 0
   and not a.attisdropped
   and a.attnotnull;
Run Code Online (Sandbox Code Playgroud)

(请注意,这也将包括与主键相关的字段,因此您需要将它们过滤掉。)

如果您这样做,请不要忘记quote_ident()在您需要处理列名称中潜在的奇怪字符时使用。