Room 的“onDelete = CASCADE”在迁移期间不起作用

Room's `onDelete = CASCADE` not working during a migration

我有以下 tables:

@Entity(
    tableName = "users"
)
class Users {
    @PrimaryKey(autoGenerate = true)
    var id: Long? = null

    @NonNull
    var name: String? = null
}

@Entity(
    tableName = "pets",
    foreignKeys = [
        ForeignKey(
            entity = Users::class,
            parentColumns = ["id"],
            childColumns = ["owner_id"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
class Pets {
    @PrimaryKey(autoGenerate = true)
    var id: Long? = null

    @NonNull
    var name: String? = null

    @ColumnInfo(name = "owner_id")
    var ownerId: Long? = null
}

当我 运行 删除所有用户 table 行的迁移时,宠物 table 不受影响。行不会自动删除。

object Migration_1_2 : Migration(1, 2) {

    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("""
            DELETE FROM users
        """)
    }
}

即使我在迁移之前执行了以下代码片段,它也不起作用。

database.execSQL("PRAGMA foreign_keys=ON;");

我应该怎么做才能使 onDelete = ForeignKey.CASCADE 正常工作?

正如@sergiytikhonov 在他的评论中指出的那样,在迁移函数中启用 foreign_keys 约束没有任何效果。这是因为 migrations are executed as part of a transaction and the pragma is a no-op inside a transaction.

我看不出有任何方法可以在执行迁移之前获得控制权并启用 foreign_keys。我认为您唯一的选择是在迁移过程中明确删除宠物:

override fun migrate(database: SupportSQLiteDatabase) {
    database.execSQL("""
        DELETE FROM pets WHERE owner_id IN (SELECT id FROM users)
    """)

    database.execSQL("""
        DELETE FROM users
    """)
}