mariadb H2中不支持删除外键

j7dteeu8  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(53)

我有一个DB(MariaDB),我需要从其中删除一个外键。没有什么会更容易,因为

alter table people_contacts
drop foreign key people_contacts;

字符串
当然,假设上面是表和键的名称 *
但我在这里问是因为一个“外部”的复杂性。Application是一个Java应用程序,它使用:

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

因此,在测试期间,我运行了一个H2数据库,显然H2不支持drop foreign key。我整天都在尝试使用H2兼容性属性,唯一的结果是有时会更改错误。
因此,我无法创建一个唯一的迁移脚本,该脚本应该 * 在嵌入测试数据库时首先在H2* 中运行,然后 * 在真实的数据库(包括生产数据库)中的MariaDB* 上运行。我可能会创建不同版本的迁移,但我真的希望避免这种方法。
有没有人能想到变通办法?
提前感谢!

6ie5vjzr

6ie5vjzr1#

虽然认为解决我的问题的唯一方法是重建表,但我发现这是另一个强有力的理由。

总之

如果以标准方式使用,则没有问题或与drop本身不兼容。

我的空投指令

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的生存时间只有几毫秒,后来它被销毁了),我打开了创建表的命令行,发现它被创建为

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


这样一来,约束就不会被明确地命名,而它的名字将是依赖于数据库的。我在持久化数据库上发现的名字没有被明确地命名,我没有意识到这是一个早期的错误,不符合项目的实践。所以(* 对不起!*)我没有检查原始的约束,而是向H2收取了不兼容性费用。
约束应创建为

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


为了确保在H2和MariaDB中都是用给定的名称创建的,并且如果需要的话,可以在以后使用给定的名称来删除它。
当然,约束的工作方式没有问题,类似的错误可能不会被发现,直到您需要删除这样的约束,并且需要按名称调用它。

吸取教训

**始终使用显式名称来命名约束,因为将来您可能需要“按名称调用它们”来删除或更改它们。

不幸的是,我发现他们中的一些人在时间上被错误地创建了。我想解决这个问题的方法是:
1.将表的后缀重命名为“old”
1.使用具有显式名称的约束重新生成表
1.将旧表中的所有数据重新插入新表
1.放下“旧”table

相关问题