I have a problem migrating my Room database. In updated database I have to change one field from integer to double value. I read its not as easy as it sounds and in order to do that I have to create new temporary table with this changed property, copy all values from previous table, delete old one and finally rename the temporary table.
My entity has 2 indices, which are causing problems. Here is my current best solution that is not passing auto generated room migration validation.
oceny is the name of the original table, oceny_temp is the temportary name. Even though i am adding those indices in explicitly with create index the validation is still not passing as it says that in expected table has 2 indices and in found there is 0.
static final Migration MIGRATION_25_26 = new Migration(25,26) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS oceny_temp" +
"(`idOceny` TEXT NOT NULL, " +
"`idUcznia` TEXT, " +
"`idPrzedmiotu` TEXT, " +
"`semestr` INTEGER NOT NULL, " +
"`typOceny` INTEGER NOT NULL, " +
"`wartosc` TEXT, " +
"`wartoscDoSredniej` REAL, " +
"`czyProponowana` INTEGER NOT NULL, " +
"`kategoria` TEXT, " +
"`waga` REAL NOT NULL, " +
"`maxPunktow` REAL NOT NULL, " +
"`odczytana` INTEGER NOT NULL, " +
"`dataWystawienia` TEXT, " +
"`wystawiajacy` TEXT, " +
"`typOczekiwania` INTEGER NOT NULL, " +
"`wersjaRekordu` TEXT, " +
"`rekordUsuniety` INTEGER NOT NULL, " +
"PRIMARY KEY(`idOceny`), " +
"FOREIGN KEY(`idUcznia`) REFERENCES `uczniowie`(`idUcznia`) ON UPDATE NO ACTION ON DELETE CASCADE )");
database.execSQL("CREATE INDEX IF NOT EXISTS index_oceny_idPrzedmiotu ON oceny_temp (idPrzedmiotu)");
database.execSQL("CREATE INDEX IF NOT EXISTS index_oceny_idUcznia ON oceny_temp (idUcznia)");
// Copy the data
database.execSQL(
"INSERT INTO oceny_temp (idOceny, idUcznia, idPrzedmiotu, semestr, typOceny, wartosc, wartoscDoSredniej, czyProponowana, kategoria, waga, maxPunktow, odczytana, dataWystawienia, wystawiajacy, typOczekiwania, wersjaRekordu, rekordUsuniety) " +
"SELECT idOceny, idUcznia, idPrzedmiotu, semestr, typOceny, wartosc, wartoscDoSredniej, czyProponowana, kategoria, waga, maxPunktow, odczytana, dataWystawienia, wystawiajacy, typOczekiwania, wersjaRekordu, rekordUsuniety FROM oceny");
// Remove the old table
database.execSQL("DROP TABLE oceny");
// Change the table name to the correct one
database.execSQL("ALTER TABLE oceny_temp RENAME TO oceny");
}
};
The error message:
Migration didn't properly handle
oceny(de.wolterskluwer.idziennik.model.grades.Grade).
Expected:
TableInfo{name='oceny', columns={dataWystawienia=Column{name='dataWystawienia', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, typOczekiwania=Column{name='typOczekiwania', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, idPrzedmiotu=Column{name='idPrzedmiotu', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, kategoria=Column{name='kategoria', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, rekordUsuniety=Column{name='rekordUsuniety', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, wystawiajacy=Column{name='wystawiajacy', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, wersjaRekordu=Column{name='wersjaRekordu', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, maxPunktow=Column{name='maxPunktow', type='REAL', affinity='4', notNull=true, primaryKeyPosition=0}, czyProponowana=Column{name='czyProponowana', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, typOceny=Column{name='typOceny', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, semestr=Column{name='semestr', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, waga=Column{name='waga', type='REAL', affinity='4', notNull=true, primaryKeyPosition=0}, odczytana=Column{name='odczytana', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, idUcznia=Column{name='idUcznia', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, idOceny=Column{name='idOceny', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}, wartosc=Column{name='wartosc', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, wartoscDoSredniej=Column{name='wartoscDoSredniej', type='REAL', affinity='4', notNull=false, primaryKeyPosition=0}}, foreignKeys=[ForeignKey{referenceTable='uczniowie', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[idUcznia], referenceColumnNames=[idUcznia]}], indices=[Index{name='index_oceny_idPrzedmiotu', unique=false, columns=[idPrzedmiotu]}, Index{name='index_oceny_idUcznia', unique=false, columns=[idUcznia]}]}
Found:
TableInfo{name='oceny', columns={dataWystawienia=Column{name='dataWystawienia', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, typOczekiwania=Column{name='typOczekiwania', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, idPrzedmiotu=Column{name='idPrzedmiotu', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, kategoria=Column{name='kategoria', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, rekordUsuniety=Column{name='rekordUsuniety', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, wystawiajacy=Column{name='wystawiajacy', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, wersjaRekordu=Column{name='wersjaRekordu', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, maxPunktow=Column{name='maxPunktow', type='REAL', affinity='4', notNull=true, primaryKeyPosition=0}, czyProponowana=Column{name='czyProponowana', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, typOceny=Column{name='typOceny', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, semestr=Column{name='semestr', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, waga=Column{name='waga', type='REAL', affinity='4', notNull=true, primaryKeyPosition=0}, odczytana=Column{name='odczytana', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, idUcznia=Column{name='idUcznia', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, idOceny=Column{name='idOceny', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}, wartosc=Column{name='wartosc', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, wartoscDoSredniej=Column{name='wartoscDoSredniej', type='REAL', affinity='4', notNull=false, primaryKeyPosition=0}}, foreignKeys=[ForeignKey{referenceTable='uczniowie', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[idUcznia], referenceColumnNames=[idUcznia]}], indices=[]}
Additional info: i added IF NOT EXISTS to the create index, because it was crashing saying that the index already exists, which doesn't make sense to me
It seems like some how the indices are lost when the table is renamed. So I resolved this issue by adding one more line after renaming my temporal table to the correct one. This creates the indices on the renamed table. For your case it would be like this ...
// Change the table name to the correct one
database.execSQL("ALTER TABLE oceny_temp RENAME TO oceny");
// Create the indices on the table
database.execSQL("CREATE INDEX IF NOT EXISTS index_oceny_idPrzedmiotu ON oceny (idPrzedmiotu)");
database.execSQL("CREATE INDEX IF NOT EXISTS index_oceny_idUcznia ON oceny (idUcznia)");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With