【发布时间】: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>
我们随后注意到,可能有多个记录具有相同的source 和external_id ()。提交数据的小组定期提交数据,他们向我们保证,他们绝不会在同一批数据中使用source 和external_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]
如果我尝试将主键作为 <constraint> 包含在我们添加不可为空约束的 changeSet 中,那么我基本上被告知我不能在那里使用 <constraints> 而是需要一个<addXxxConstraint> 的列表,列表中有一个 <addPrimaryKey> — 这听起来像是正确的约束。
因此,如果我将第二个 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'.
那么,如何向现有的复合主键添加一个新的不可为空的字段?
【问题讨论】: