H2数据库不支持删除外键,求Flyway跨库迁移兼容方案
解决MariaDB与H2数据库删除外键的Flyway迁移兼容问题
方法1:用Flyway占位符实现单脚本多适配
Flyway支持根据环境变量或配置文件的参数,自动替换SQL里的片段,不用拆分多版本脚本:
- 先给测试环境(H2)和生产环境(MariaDB)分别配置标识,比如在
flyway.conf里,测试环境加db.type=h2,生产环境加db.type=mariadb - 迁移脚本里写带占位符的SQL:
${db.type:mariadb}ALTER TABLE people_contacts DROP FOREIGN KEY people_contacts; ${db.type:h2}ALTER TABLE people_contacts DROP CONSTRAINT people_contacts;
Flyway会根据当前环境的db.type值,只执行对应数据库的语句。
方法2:强制H2启用MariaDB兼容模式
如果之前调兼容配置没生效,试试给H2连接URL加完整的兼容参数:
- 测试环境的H2连接URL改成:
jdbc:h2:mem:testdb;MODE=MARIADB;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH - 开启这个模式后,H2会完全模拟MariaDB的语法,包括
DROP FOREIGN KEY,原脚本就能直接在H2里跑通
方法3:用Java迁移类做逻辑判断
放弃纯SQL脚本,写个Java迁移类,在代码里识别数据库类型再执行对应语句:
import org.flywaydb.core.api.migration.BaseJavaMigration; import org.flywaydb.core.api.migration.Context; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; public class V1__Drop_People_Contacts_Foreign_Key extends BaseJavaMigration { @Override public void migrate(Context context) throws SQLException { Connection conn = context.getConnection(); DatabaseMetaData meta = conn.getMetaData(); String dbName = meta.getDatabaseProductName(); String sql; if ("H2".equals(dbName)) { sql = "ALTER TABLE people_contacts DROP CONSTRAINT people_contacts"; } else { sql = "ALTER TABLE people_contacts DROP FOREIGN KEY people_contacts"; } conn.createStatement().execute(sql); } }
这种方式靠代码逻辑适配,不用维护多份SQL,一次写完两边都能用。
内容的提问来源于stack exchange,提问作者angelodelia
相关产品推荐
相关产品推荐

