【问题标题】:In Liquibase, how to add a new column/field to an existing composite primary key在 Liquibase 中,如何向现有复合主键添加新列/字段
【发布时间】:2020-06-30 01:16:41
【问题描述】:

我们有一个现有表,其中有 2 个现有列用作复合主键。它们的设置与此非常相似:

<!-- ???? WE CAN NO LONGER MODIFY THIS CHANGESET ???? -->

<changeSet author="an_awesome_author" id="EXAMPLE-01">
  <createTable tableName="our_awesome_table">
    <column name="source" type="varchar(32)">
      <constraints 
          primaryKey="true" 
          nullable="false" 
          primaryKeyName="CPK_OUR_AWESOME_TABLE"/>
    </column>
    <column
        name="external_id"
        type="varchar(255)">
      <constraints 
          primaryKey="true" 
          nullable="false"  
          primaryKeyName="CPK_OUR_AWESOME_TABLE"/>
    </column>
  </createTable>
</changeSet>

我们随后注意到,可能有多个记录具有相同的sourceexternal_id ()。提交数据的小组定期提交数据,他们向我们保证,他们绝不会在同一批数据中使用sourceexternal_id 的相同组合。

因此(出于此问题之外的原因)我们决定添加一个created_at 字段,该字段不可为空,并且默认为将每条记录添加到表中时。这并不难,例如我们可以运行这对changeSets

<!-- WE ARE TRYING TO FINALIZE THESE CHANGESETS -->

<changeSet author="yours_truly"
           id="EXAMPLE-02-01">
  <addColumn tableName="our_awesome_table">
    <column name="CREATED_AT"
            type="datetime"
            valueDate="current_datetime"
            defaultValueDate="current_datetime" />
    <!-- the above:
      adds the new field
      sets the type
      adds the current timestamp to existing records
      will default to the current timestamp for new records
    -->
  </addColumn>
</changeSet>
<changeSet author="yours_truly"
           id="EXAMPLE-02-02">
  <addNotNullConstraint tableName="our_awesome_table"
                        columnName="CREATED_AT"/>
  <!-- the above:
    now that every record has a value in the newly created field,
    we can add a constrant preventing null entries into the column
  -->
</changeSet>

但是,我们还需要将created_at 添加到我们现有的复合主键中!

如果我在创建字段时尝试包含主键作为约束,它会抱怨表只能有一个主键 -尽管事实上它已经是一个复合键并且我'我只是尝试将其添加到已经存在的复合键中。但它也抱怨created_at 时间戳为空。所以,我不确定哪个是实际问题????‍♂️,但在这里绝对行不通。

例如

<changeSet author="yours_truly"
           id="EXAMPLE-02-01">
  <addColumn tableName="our_awesome_table">
    <column name="CREATED_AT"
            type="datetime"
            valueDate="current_datetime"
            defaultValueDate="current_datetime">
      <constraints primaryKey="true"
                   primaryKeyName="PK_OUR_AWESOME_TABLE"/>
      <!-- this constraints causes multiple problems -->
    </column>
  </addColumn>
</changeSet>

结果如下:

[ERROR]      Reason: liquibase.exception.DatabaseException: ORA-02260: table can have only one primary key
[ERROR]  [Failed SQL: ALTER TABLE OUR_AWESOME_TABLE.OUR_AWESOME_TABLE ADD CREATED_AT TIMESTAMP DEFAULT SYSTIMESTAMP PRIMARY KEY NOT NULL]

如果我尝试将主键作为 &lt;constraint&gt; 包含在我们添加不可为空约束的 changeSet 中,那么我基本上被告知我不能在那里使用 &lt;constraints&gt; 而是需要一个&lt;addXxxConstraint&gt; 的列表,列表中有一个 &lt;addPrimaryKey&gt; — 这听起来像是正确的约束。

因此,如果我将第二个 changeSet 更改为这样的内容,我希望它可以工作:

<changeSet author="yours_truly"
           id="EXAMPLE-02-02">
  <addNotNullConstraint tableName="our_awesome_table"
                        columnName="CREATED_AT"/>
  <addPrimaryKey tableName="our_awesome_table"
                 columnNames="CREATED_AT"
                 primaryKeyName="CPK_OUR_AWESOME_TABLE"/>
</changeSet>

但是——你可能猜到了——它不起作用。相反,它告诉我,cvc-complex-type.3.2.2: Attribute 'primaryKeyName' is not allowed to appear in element 'addPrimaryKey'.


那么,如何向现有的复合主键添加一个新的不可为空的字段?

【问题讨论】:

    标签: oracle liquibase


    【解决方案1】:

    addPrimaryKey-Type 没有 primaryKeyName 属性 - 可以通过 constraintName 设置约束的名称。

    但它不起作用,因为您无法更改 oracle 中的主键。相反,您必须 drop the primary key (并且很可能是相应的索引)然后重新创建它,包括您想要在 columnNames 中的列:

    <changeSet author="yours_truly"
               id="EXAMPLE-02-02">
      <addNotNullConstraint tableName="our_awesome_table"
                            columnName="CREATED_AT"/>
    
      <dropPrimaryKey tableName="our_awesome_table"
                     dropIndex="true"
                     constraintName="CPK_OUR_AWESOME_TABLE"/>
    
      <addPrimaryKey tableName="our_awesome_table"
                     columnNames="external_id, created_at"
                     constraintName="CPK_OUR_AWESOME_TABLE"/>
    </changeSet>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-21
      • 2016-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-11
      • 2022-01-01
      相关资源
      最近更新 更多