Room's `onDelete = CASCADE` не работает во время миграции - PullRequest
1 голос
/ 28 мая 2020

У меня есть следующие таблицы:

@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 не изменяется. Строки не удаляются автоматически.

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 работа?

1 Ответ

0 голосов
/ 02 июня 2020

Как указывает @sergiytikhonov в своем комментарии, включение ограничения foreign_keys в функции миграции не имеет никакого эффекта. Это связано с тем, что миграции выполняются как часть транзакции и прагма не работает внутри транзакции .

Я не вижу никакого способа получить контролируйте и активируйте 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
    """)
}
...