Android - Комната, как добавить ссылку на внешний ключ для переноса данных

Я обновил один из объектов Room, включив в него внешний ключ. Теперь я должен включить это изменение в свою миграцию данных, но не уверен в SQL-запросе.

Я пробовал следующее, но он не компилируется:

private val MIGRATION_1_2 = object: Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE `Entity` ADD FOREIGN KEY(`parent_id`) 
                REFERENCES `Entity`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE)")
    }
}

какую ошибку вы получаете?

Itamar Kerbel 30.05.2019 15:47

Кроме того, я думаю, что у вас есть лишняя скобка

Itamar Kerbel 30.05.2019 15:48

Вот аналогичный вопрос и ответ.

Mahozad 23.01.2022 09:22
5
3
2 586
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В SQLite изменение таблицы для добавления внешнего ключа невозможно, по крайней мере, в соответствии с этим документация SQLite:

Only the RENAME TABLE, ADD COLUMN, and RENAME COLUMN variants of the ALTER TABLE command are supported. Other kinds of ALTER TABLE operations such as DROP COLUMN, ALTER COLUMN, ADD CONSTRAINT, and so forth are omitted.

Имея это в виду, я думаю, что правильным способом переноса базы данных будет:

  1. Создайте новую временную таблицу,
  2. Скопируйте значения из старой таблицы во временную таблицу,
  3. Бросьте старый стол,
  4. Переименуйте временную таблицу в старое имя таблицы.

В вашем случае это, вероятно, будет выглядеть так:

override fun migrate(database: SupportSQLiteDatabase) {
    // Create a new translation table
    database.execSQL("CREATE TABLE IF NOT EXISTS `Entity_new` (" +
        "`old_column_1` TEXT NOT NULL, " +
        "`old_column_2` TEXT NOT NULL, " +
        "`parent_id` INTEGER, " +
        "`entity_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
        "FOREIGN KEY(`parent_id`) REFERENCES `Entity`(`entity_id`) ON UPDATE NO ACTION ON DELETE CASCADE )")
    // Copy the data
    database.execSQL("INSERT INTO `Entity_new` (old_column_1, old_column_2, entity_id) " +
        "SELECT old_column_1, old_column_2, entity_id " +
        "FROM Entity")
    // Remove old table
    database.execSQL("DROP TABLE Entity")
    // Change name of table to correct one
    database.execSQL("ALTER TABLE Entity_new RENAME TO Entity")
}

Отказ от ответственности: я взял код из этого очень полезного Проект PersistenceMigrationSample.

Другие вопросы по теме

Как создать текущую последовательность в Oracle на основе значений столбца отчета
Обновление значений для всех строк на основе уникального идентификатора — Oracle
Таблица событий запросов BigQuery
Как вставить массив объектов JSON в PostgreSQL как отдельные элементы
Проверьте, имеет ли строка определенное окончание, сотрите это окончание, затем запишите эти строки в соответствии с двумя другими условиями
Учитывая увеличивающиеся значения идентификатора и созданную дату, создайте оператор SQL, чтобы определить, не совпадают ли какие-либо даты с идентификатором в оракуле
Различные строки для результатов при использовании оператора case SQL для одного и того же значения
Выбрать данные, где условие соответствует, и если нет, то выбрать все?
Ошибка оператора Group BY для получения уникальных записей
Измените последовательность с помощью SQL Query