H2 不支持删除外键

问题描述 投票:0回答:1

我有一个数据库(MariaDB),我需要从中删除外键。没有什么比这更容易了,因为

alter table people_contacts
drop foreign key people_contacts;

完美地完成工作。 当然,假设上面是表和键的名称

但我来这里询问是因为“外部”并发症。应用程序是一个 Java 应用程序,它使用:

  • Flyway执行数据库迁移
  • GitHub actions 运行自动测试。

因此,在测试过程中我运行了 H2 数据库,显然 H2 不支持

drop foreign key
。我一整天都在尝试使用 H2 兼容性属性,唯一的结果是有时会更改错误。

因此,我无法创建一个独特的迁移脚本,该脚本应该在嵌入测试数据库时首先在 H2 中运行,然后在实际数据库(包括生产)中的 MariaDB 上运行。我可能会创建不同版本的迁移,但我真的很想避免这种方法。 有人会看到任何解决方法吗? 提前致谢!

虽然认为解决问题的唯一方法是重建表,但我发现这样做还有另一个重要原因。

sql mariadb foreign-keys h2 flyway
1个回答
0
投票

如果按照标准方式使用,掉落本身没有问题或不兼容。

我的放置命令 alter table people_contacts drop foreign key people_contacts_fk;

不是

SQL 标准
方式,它应该是

ALTER TABLE people_contacts DROP CONSTRAINT people_contacts_fk 正如@evgenijryazanov 在他的评论中指出的那样。 在 H2 中它会完美地工作,但在我的例子中,我抱怨该名称缺乏约束。 这实际上是我在创建表格时遇到的问题。

详情

调查 H2 中未找到的约束(请注意,H2 DB 的生命周期为几毫秒,随后被销毁),我打开了创建表的 DDL,发现它被创建为

create table people_contacts ( ... fields ..., foreign key (person_id) references people (id) );

通过这种方式,约束不会被赋予显式名称,并且它将具有的名称将取决于数据库。我在持久数据库中找到的名称没有明确给出,而且我没有意识到它,因为这是一个早期的错误,不符合项目的实践。 所以(

抱歉!
)我没有检查原始 DDL,而是向 H2 收取不兼容性费用。

约束应创建为 create table people_contacts ( ... fields ..., constraint explicit_name_for_it foreign key (person_id) references people (id) );

为了确保在 H2 和 MariaDB 中都使用给定名称创建,并且稍后可以根据需要使用给定名称删除它。

当然,约束的工作方式没有问题,并且类似的错误可能仍然未被发现,直到您需要删除这样的约束并且需要通过名称来调用它。

吸取的教训

始终让约束具有明确的名称,因为将来您可能需要“按名称调用它们”来删除或更改它们。

不幸的是,我发现其中一些是错误地创建的。我想解决这个问题的方法是:

将后缀为“old”的表重命名

使用具有显式名称的约束重建表
  1. 将旧表中的所有数据重新插入新表中
  2. 放弃“旧”表。
© www.soinside.com 2019 - 2024. All rights reserved.