Я использую базу данных комнат У меня есть таблица, в которую я забыл добавить onDelete = CASCADE
Предыдущая версия
@Entity(indices = {@Index(value = {"info_id"})}, foreignKeys = @ForeignKey(entity = StudentClass.class, parentColumns = "id", childColumns = "info_id"))
Что я хочу сейчас
@Entity(indices = {@Index(value = {"info_id"})}, foreignKeys = @ForeignKey(entity = StudentClass.class, parentColumns = "id", childColumns = "info_id", onDelete = CASCADE))
Я пытаюсь перенести базу данных
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("What should I do here to add onDelete = CASCADE");
}
};
Хорошо, наконец, я нашел решение
database.execSQL("CREATE TABLE attendance_temp(attendanceId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, time INTEGER NOT NULL, student_id INTEGER, student_name TEXT , roll_number INTEGER, image_path TEXT, info_id INTEGER, present INTEGER , CONSTRAINT fk_class_info FOREIGN KEY (info_id) REFERENCES class_info(id) ON DELETE CASCADE)");
database.execSQL("INSERT INTO attendance_temp SELECT * FROM Attendance");
database.execSQL("DROP TABLE Attendance");
database.execSQL("ALTER TABLE attendance_temp RENAME TO Attendance");
database.execSQL("CREATE INDEX index_Attendance_info_id ON Attendance(info_id)");
Также измените схему в классе сущности на
@Entity(indices = {@Index(value = {"info_id"})}, foreignKeys = @ForeignKey(entity = StudentClass.class, parentColumns = "id", childColumns = "info_id", onDelete = CASCADE))
Последовательность важна.
SQLite не полностью поддерживает стандарт SQL ALTER TABLE:
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. Rename your table
database.execSQL("ALTER TABLE Entity RENAME TO Entity_old")
// 2. Recreate the same entity, but now with the constraint
database.execSQL("""
CREATE TABLE Entity(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
parentId INTEGER,
someField STRING,
CONSTRAINT fk_Entity_entityId_EntityParent_id FOREIGN KEY (entityId) REFERENCES EntityParent(id) ON DELETE CASCADE
)
""")
// 3. Copy the data from the old table
database.execSQL("INSERT INTO Entity SELECT * FROM Entity_old")
// 4. Delete old table
database.execSQL("DROP TABLE Entity_old")
// 5. Recreate the indices
database.execSQL("CREATE INDEX index_Entity_id ON Entity(id)")
Ого, это, к сожалению, так больно :(