Сбой ограничения NOT NULL при копировании данных в новую таблицу - PullRequest
0 голосов
/ 10 января 2019

Я перенесу свою базу данных из SQLiteOpenHelper в Room.

У меня есть таблица, которую я хочу изменить, назовем ее "my_table". Это упрощенное утверждение создания:

CREATE TABLE `my_table`
 (`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
  `title` TEXT
 )

Во время обновления среди других изменений я добавляю новый столбец type INTEGER NOT NULL (я также добавляю внешний ключ и делаю другие существенные изменения, поэтому я создаю новую таблицу вместо того, чтобы изменять существующую):

CREATE TABLE "new_table" 
 (`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
  `title` TEXT,
  `type` INTEGER NOT NULL
 )

Затем я хочу скопировать данные из my_table в new_table и установить значения столбца type.

Оператор SQL:

INSERT INTO new_table (title) 
SELECT title FROM my_table;
UPDATE new_table SET type = 1;
DROP TABLE my_table;
ALTER TABLE new_table RENAME TO my_table;

Миграция Android:

public static final Migration MIGRATION_TEST = new Migration(1, 2) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        // Create new table
        database.execSQL("CREATE TABLE new_table (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT, `type` INTEGER NOT NULL)");
        // Copy some data
        database.execSQL("INSERT INTO new_table (title) SELECT title FROM old_table"); // constraint violation
        // Insert default value into the measures column
        database.execSQL("UPDATE new_table SET type = 1");
        // Delete old table
        database.execSQL("DROP TABLE old_table");
        // Rename new table
        database.execSQL("ALTER TABLE new_table RENAME TO my_table");
    }
};

Очевидно, я получаю NOT NULL constraint failed: new_table.type ошибка:

android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: new_table.type (code 1299)
Error Code : 1299 (SQLITE_CONSTRAINT_NOTNULL)
Caused By : Abort due to constraint violation.
(NOT NULL constraint failed: new_table.type (code 1299))

Я могу избежать этого, изменив оператор создания новой таблицы и установив значение по умолчанию для столбца type.

CREATE TABLE "new_table" 
 (`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
  `title` TEXT,
  `type` INTEGER NOT NULL DEFAULT 1
 )

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

Существуют ли обходные пути, позволяющие избежать этой ошибки при вставке данных в новую таблицу?

1 Ответ

0 голосов
/ 10 января 2019

Я думаю, что может работать следующее: -

database.execSQL("INSERT INTO new_table (title,type) SELECT title, 1 FROM old_table");

То есть, теперь вы говорите INSERT 2 столбца согласно инструкции SELECT. SELECT возвращает 2 значения заголовка из old_table и буквального значения 1.

Тебе тогда не понадобится database.execSQL("UPDATE new_table SET type = 1").

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...