Я перенесу свою базу данных из 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 не поддерживает значения по умолчанию из коробки и во избежание ошибок в будущем при вставке новых значений в таблицы.
Существуют ли обходные пути, позволяющие избежать этой ошибки при вставке данных в новую таблицу?