Liquibase如何在不知道约束名的情况下删除约束

12
我们使用liquibase来跟踪我们的数据库更改... 第一个changeSet包含以下内容:
<column name="SHORT_ID" type="INTEGER">
   <constraints unique="true" />
</column>
基本上,它意味着SHORT_ID列具有唯一约束条件,但是此约束条件的名称可以是任何名称,通常每次都不同(我们针对H2数据库运行一些集成测试,每次运行测试时都会创建新的数据库)。
那么...问题是:我不能更改这个第一个changeSet,但现在我们必须摆脱这个唯一约束条件。 有什么想法可以通过使用liquibase实现这一点吗?
3个回答

8
Liquibase提供了一个实现方法,可以在不知道约束名的情况下删除非空约束。当问这个问题时,可能还不存在(我意识到它很古老)。请参考dropNotNullConstraint
<dropNotNullConstraint catalogName="cat"
            columnDataType="int"
            columnName="id"
            schemaName="public"
            tableName="person"/>

有一个dropUniqueConstraint,但你可能已经知道了它需要约束名称。


5

H2的SQL删除约束需要指定约束名称。我不记得H2自动生成的约束名是随机的还是在数据库间保持一致。

如果是一致的,你可以使用普通的liquibase标签,它会正常工作。

如果是随机的,你将不得不从information_schema中获取约束名称。H2可能允许类似以下的操作:

alter table TABLE_NAME drop constraint 
      (select unique_index_name 
              from information_schema.constraints 
              where table_name='TABLE_NAME' and column_name='SHORT_ID')

如果不行的话,您可能需要创建一个自定义的Liquibase更改(在2.0版本中使用http://liquibase.org/extensions,在1.9版本中使用http://www.liquibase.org/manual/custom_refactoring_class),以进行调用并删除约束。

2
之前尝试过了...在删除约束命令中不能有选择子句 :) 而且约束名称也不一致..我试图避免使用那些自定义重构类,但似乎只有这个选项..所以感谢您的方法和+1,如果没有人提出不需要自定义Liquibase更改的解决方案,那么这个答案将被接受.. ;] - vrm
1
我在使用 MS SQL Server 时遇到了相同的问题,即无法在 DROP CONSTRAINT 命令中使用 SELECT。最终我采用了以下方法,针对容器表中 col measurements 的唯一约束删除操作:https://bowerstudios.com/node/995(链接因评论框中的字符不足而提供)。解决方案与 Nathan 的相似,但针对 MS SQL Server 进行了调整。 - Daniel Bower

1
对于HSQL,Nathan建议的查询不起作用(alter table TABLE_NAME drop constraint (select unique_index_name from information_schema.constraints where table_name='TABLE_NAME' and column_name='SHORT_ID'))。
这是因为DDL和SQL不能混合使用。
在运行时通过已知名称删除约束似乎在HSQL中不可能(我需要在删除带有约束的列之前进行回滚)。这适用于Oracle和MSSQL。
我所做的是通过hbm文件(hibernate)获取生成的数据库。由于Hibernate不支持命名唯一键约束,因此例如使用Liquibase无法删除带有约束的这些列(对于HSQL而言)。我们基于HSQL进行测试以测试整个内容。最好能够为HSQL获得解决方案。
目前,我只是硬编码唯一约束名称(一个解决方法)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接