我有一个外键,它是在旧的且已部署的迁移中使用以下命令生成的:
ALTER TABLE `job_template`
ADD COLUMN `parent_id` BIGINT,
ADD FOREIGN KEY fk_job_template_parent_id(parent_id) REFERENCES job_template(id) ON DELETE CASCADE;
现在我正尝试使用以下命令删除此外键:
ALTER TABLE job_template DROP FOREIGN KEY fk_job_template_parent_id;
问题是这适用于mariaDB,但不适用于mySQL,并且我需要一种在两种情况下均适用的迁移
如果我在两个环境中都列出了SHOW CREATE TABLE命令(在删除外键之前),则会得到以下信息:
mariaDB:
constraint fk_job_template_parent_id foreign key (parent_id) references job_template (id) on delete cascade,
mysql:
constraint job_template_ibfk_5 foreign key (parent_id) references job_template (id) on delete cascade,
在两种环境中约束名称是不同的,因此我无法编写将始终删除此外键的迁移。
有什么办法可以解决这种情况?
答案 0 :(得分:1)
您的问题是您没有明确命名约束。这样,每个数据库都可以为您选择一个名称。这里的技巧是在MySQL和MariaDB上创建实际表时,明确命名外键约束:
CREATE TABLE job_template (
...,
parent_id int NOT NULL,
CONSTRAINT your_constraint FOREIGN KEY fk_name (parent_id)
REFERENCES job_template(id) ON DELETE CASCADE
);
但是解决您的当前情况将需要更多的工作。一种选择是查询信息模式表,以找到所涉及的表,以找出实际的约束名称:
USE INFORMATION_SCHEMA;
SELECT
TABLE_NAME,
COLUMN_NAME,
CONSTRAINT_NAME,
REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM KEY_COLUMN_USAGE
WHERE
TABLE_SCHEMA = 'your_db' AND
TABLE_NAME = 'job_template' AND
REFERENCED_COLUMN_NAME IS NOT NULL;
这应该为每个列和约束返回一个记录。有了这些信息,您应该能够运行当前的alter语句。
使用Java之类的工具或类似工具很容易做到。如果要直接从数据库中执行此操作,则需要动态SQL,这可能意味着编写存储过程。