【问题标题】:Add a new column to PostgreSQL database, set initial value and set NOT NULL all in one go向 PostgreSQL 数据库添加新列,设置初始值并一次性设置 NOT NULL
【发布时间】:2014-09-20 08:29:17
【问题描述】:

使用 Django,我经常需要向我们的 PostgreSQL 数据库添加新字段。这些字段通常有一个初始值,并且它们必须设置为 NOT NULL。我的程序包括三个步骤:

1) 添加字段并设置初始值:

ALTER TABLE my_table ADD COLUMN my_field boolean;
UPDATE my_table SET my_field = FALSE;

2) 设置非空:

ALTER TABLE my_table ALTER COLUMN my_field SET NOT NULL;

三个查询不能同时运行,因为这会导致 PostgreSQL 错误。

执行此任务最有效的方法是什么?我想在单个查询中执行此操作 - 并一次添加多个字段。类似的东西:

ALTER TABLE my_table ADD COLUMN my_field boolean INITIAL FALSE SET NOT NULL, ADD COLUMN my_field2 boolean INITIAL FALSE SET NOT NULL;

【问题讨论】:

    标签: sql postgresql ddl alter-table


    【解决方案1】:

    你试过了吗?

    alter table my_table add column my_field1 boolean default false NOT NULL, 
                         add column my_field2 boolean default false NOT NULL;
    

    【讨论】:

    • 由于 Django 没有在数据库级别设置 DEFAULT 值,我在第二步中将其删除。尽管这个序列似乎比我原来的序列效率低,但我更喜欢你的方式,因为在我们经常使用的数据库上创建一个字段后,我经常在分配 NOT NULL 标志时遇到问题。新的空值添加得太快了......
    • 这不是根本不同吗?在海报的原始方式中,该字段获取一个初始值,但是对于下一次插入,必须指定该字段。这里你放了一个默认值,意思是如果插入时没有为这个字段指定值,false将被使用
    • 有没有办法在不设置默认值的情况下为新列设置初始值?
    【解决方案2】:

    你应该通过两个步骤来做到这一点:

    1. 添加列
    2. 更改列:设置约束,添加默认值

    查询:

    ALTER TABLE my_table ADD COLUMN my_field boolean;
    ALTER TABLE my_table ALTER COLUMN my_field SET NOT NULL,
                         ALTER COLUMN my_field TYPE boolean USING false;
    

    或者这个:

    ALTER TABLE my_table ADD COLUMN my_field boolean;
    ALTER TABLE my_table ALTER COLUMN my_field SET NOT NULL,
                         ALTER COLUMN my_field SET DEFAULT false;
    

    first 的好处是您可以根据行数据计算每行的值(换句话说,您可以引用字段)。对于DEFAULT 子句,您必须使用裸值。

    查看documentation examples 的时间戳

    【讨论】:

      【解决方案3】:

      您可以将您的 DDL 包装到一个函数中,这对您的情况来说是个好主意,下面给出了一个适合您情况的示例。

      希望它有效!

      CREATE OR REPLACE FUNCTION altertable(tablename text, colname text, coltype text,coldef text)
      RETURNS void AS
      $BODY$ 
      BEGIN 
      EXECUTE ' ALTER TABLE '|| quote_ident(tablename) || ' ADD COLUMN ' || quote_ident(colname) ||' '|| coltype ||' DEFAULT '||coldef||' NOT NULL'; END $BODY$
      LANGUAGE plpgsql VOLATILE
      
      • 兴趣点:能够更改任何表、任何列类型
      • 用法:

        select altertable('tbl1','bool_col','boolean','true')
        select altertable('tbl2','int_col','Integer','1')
        

      【讨论】:

        猜你喜欢
        • 2018-07-25
        • 2010-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-27
        • 1970-01-01
        相关资源
        最近更新 更多