【问题标题】:How to add new column with default value from existing column in Liquibase如何从 Liquibase 中的现有列添加具有默认值的新列
【发布时间】:2022-02-24 18:49:53
【问题描述】:

我正在使用 Postgres DB,而对于迁移,我正在使用 Liquibase。 我有一个包含以下列的 ORDERS 表:

ID | DATE | NAME | CREATOR | ...

我需要添加一个新列来保存上次修改订单的用户 - 此列不应为空,并且应具有默认值,即 CREATOR。 对于新订单,我可以解决业务逻辑的默认值部分,但是问题是我已经有一个现有订单,我需要在创建新列时设置默认值。 现在,我知道我可以设置一个硬编码的default value in Liquibase - 但是有没有办法可以根据该表的其他列(对于每个实体)添加默认值。

【问题讨论】:

  • postgresql 上的文档说default clause(在create table 语句上):DEFAULT 子句为其列定义所在的列分配默认数据值。该值是任何无变量表达式(不允许对当前表中的其他列进行子查询和交叉引用)... 而且我认为 liquibase 没有任何功能可以以任何方式添加它。 ..

标签: java postgresql migration liquibase


【解决方案1】:

由于这里没有人回答,所以我发布了我处理它的方式:

<changeSet id="Add MODIFY_USER_ID to ORDERS" author="Noam">
        <addColumn tableName="ORDERS">
            <column name="MODIFY_USER_ID" type="BIGINT">
                <constraints foreignKeyName="ORDERS_MODIFY_FK" referencedTableName="USERS" referencedColumnNames="ID"/>
            </column>
        </addColumn>
</changeSet>

<changeSet id="update the new MODIFY_USER_ID column to get the CREATOR" author="Noam">
    <sql>update ORDERS set MODIFY_USER_ID = CREATOR</sql>
</changeSet>

<changeSet id="Add not nullable constraint on MODIFY_USER_ID column" author="Noam">
    <addNotNullConstraint tableName="ORDERS" columnName="MODIFY_USER_ID" columnDataType="BIGINT"/>
</changeSet>

按照文档的建议,我已经在三个不同的变更集中完成了这项工作

【讨论】:

    【解决方案2】:

    您可以使用defaultValueComputed 属性,它采用过程或函数的名称。您还必须创建一个更改集来创建该过程。

    可能看起来有点像这样:

    <changeSet author="steve" id="createProcedureForDefaultValue">
        <createProcedure procedureName="myCoolProc">
        CREATE OR REPLACE PROCEDURE myCoolProc IS
        BEGIN
           -- actual logic here
        END;
        </createProcedure>
    </changeSet>
    
    <changeSet author="steve" id="addDefaultValueColumn">
        <addColumn tableName="ORDERS">
            <column name="LAST_MODIFIED_BY" type="VARCHAR" defaultValueComputed="myCoolProc">
                <constraints nullable="false"/>
            </column>
        </addColumn>
    </changeSet>
    

    或者,您可以使用&lt;sql&gt; 标记来执行此操作。

    【讨论】:

    • 感谢@SteveDonie,但程序或 SQL 中的 WHERE 子句应该是什么?
    • 我不知道你的 where 子句应该是什么 - 你没有在问题中指定条件。
    • 这里我要完成的主要是创建一个具有默认值的新列——默认值(对于表中的现有条目)应该与另一列的值相同。例如,如果我在表中已经有这样的条目: ID = 333 DATE = ... NAME = name CREATOR = Steve 我希望新创建的列将值“Steve”作为默认值 - 对于新创建的条目 - 我将处理业务逻辑中的值
    • 最终我以以下方式管理它(全部在一个变更集中):1)创建一个新的可为空列 2)使用 标签更新新列 3)添加非新列上的可为空约束
    • 请注意,&lt;addColumn&gt; 与添加非空约束相结合是不好的做法。如果表包含数据,它将失败。请参阅主题:Adding a non-nullable column to existing table fails
    【解决方案3】:

    你可以试试这个:

    <column name="columnName" type="VARCHAR(255 BYTE)" defaultValue="def_value" value="def_value">
    

    问候, L.

    【讨论】:

      猜你喜欢
      • 2021-01-17
      • 1970-01-01
      • 2016-09-08
      • 1970-01-01
      • 2017-08-31
      • 1970-01-01
      • 2011-06-25
      • 1970-01-01
      • 2022-01-13
      相关资源
      最近更新 更多