我正在尝试使用数据库提供程序编写一个新的迁移来更新我们的sqlite数据库。在其文档ALTER TABLE中描述了更改色谱柱的过程。
我需要对一个父表进行更改,该表具有外键约束设置为删除时级联的子表。我已经实现了文档中的步骤,但是当我删除旧表时,它会删除子表中的所有记录。文档中的步骤:
1.创建新表
1.复制数据
1.删除旧表
1.将新的重命名为旧的
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(
"PRAGMA foreign_keys=off;\r\n" +
"PRAGMA ignore_check_constraints = on;" +
"PRAGMA legacy_alter_table=on;\r\n" +
// Step 1.
"CREATE TABLE \"PROCEDURES_TEMP\" (\r\n" +
" \"PROCEDURE_ID\" TEXT NOT NULL CONSTRAINT \"PK_PROCEDURES\" PRIMARY KEY,\r\n" +
" \"DESCRIPTION\" TEXT NOT NULL,\r\n" +
" \"IS_PRODUCTION\" INTEGER NOT NULL DEFAULT (0)\r\n" +
");\r\n" +
// Step 2.
"INSERT INTO \"PROCEDURES_TEMP\"(\"PROCEDURE_ID\", \"DESCRIPTION\", \"IS_PRODUCTION\")\r\n" +
"SELECT \"PROCEDURE_ID\", \"DESCRIPTION\", \"IS_PRODUCTION\" \r\n" +
"FROM \"PROCEDURES\";\r\n" +
// Step 3.
"DROP TABLE \"PROCEDURES\";\r\n" +
// Step 4.
"ALTER TABLE \"PROCEDURES_TEMP\" RENAME TO \"PROCEDURES\";\r\n" +
"PRAGMA foreign_keys=on;\r\n" +
"PRAGMA ignore_check_constraints = off;" +
"PRAGMA legacy_alter_table=off;\r\n"
);
}
子表看起来像
CREATE TABLE \"FLOWS\" (
\"FLOW_ID\" INTEGER NOT NULL,
\"PROCEDURE_ID\" TEXT NOT NULL,
\"DESCRIPTION\" TEXT NULL,
\"SEQUENCE_NUMBER\" INTEGER NOT NULL DEFAULT (1),
CONSTRAINT \"PK_FLOWS\" PRIMARY KEY (\"FLOW_ID\", \"PROCEDURE_ID\"),
CONSTRAINT \"FK_FLOWS_PROCEDURES\" FOREIGN KEY (\"PROCEDURE_ID\") REFERENCES \"PROCEDURES\" (\"PROCEDURE_ID\") ON DELETE CASCADE\r\n);
我不是100%的级联删除是什么导致的问题。如果我不删除旧表,所有数据仍然存在。我已经尝试了许多不同的版本,比如将其改为两个操作而不是一个。是否需要临时存储所有子数据并重新插入?我是不是漏掉了什么?
1条答案
按热度按时间0qx6xfy61#
我在更改两个表的迁移中遇到了此问题。问题是一个表是另一个表的父表。
自动生成的迁移代码逐个独立地处理这两个表。在我的例子中,解决方案是重新排序代码,首先将 * 两个 * 表的行复制到临时表,然后 * 删除并重新创建两个表并复制回数据。
自动生成的代码看起来像这样(简化):
我重新排序了语句,这样做:
如果您的子表没有被迁移更改,您仍然可以通过预先保存子表行并重新插入它们来解决这个问题。