Room 的 `onDelete = CASCADE` 在迁移过程中不起作用 [英] Room's `onDelete = CASCADE` not working during a migration

查看:52
本文介绍了Room 的 `onDelete = CASCADE` 在迁移过程中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下表格:

@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
}

当我运行删除所有用户表行的迁移时,pets 表不受影响.这些行不会自动删除.

When I run a migration that deletes all users table rows, the pets table is not affected. The rows are not automatically deleted.

object Migration_1_2 : Migration(1, 2) {

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

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

Even when I execute the following snippet of code before the migration it does not work.

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

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

What should I do to make the onDelete = ForeignKey.CASCADE work?

推荐答案

正如@sergiytikhonov 在他的评论中所指出的,在迁移函数中启用foreign_keys 约束没有任何效果.这是因为 迁移执行为交易的一部分pragma 是事务中的 no-op.

As @sergiytikhonov indicates in his comment, enabling the foreign_keys constraint in a migration function has no effect. This is because migrations are executed as part of a transaction and the pragma is a no-op inside a transaction.

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

I don't see any way to get control and enable foreign_keys before the migration is executed. I think your only option is to delete the pets explicitly as part of the migration:

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

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

这篇关于Room 的 `onDelete = CASCADE` 在迁移过程中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆