Roomを使っているAndroidアプリで、DBスキーマの変更(列の型変更)の必要が発生しました。その際、マイグレーションをしないと実行時にエラーとなってしまいます。
その際の対応メモです。
言語はJavaです。
なお、DBファイルは例外的な方法ですが、アプリ内でスキーマを変更せず、PC上で変更してAndroidデバイス側に持ってくる仕様としています。
(DBファイル自体もアプリ固有領域ではなく、外部ストレージ= Context#getExternalFilesDir に配置)
1.DBの変更
上記に書いたように、今回DBファイルはPC側から持ってくるという仕様としています。
それでPC側で、DB Browser for SQLite 等を使ってスキーマを変更します。
今回のDBスキーマの変更は、列の型の変更です。
余談ですが、SQLiteでの型変更も少し厄介で、以下を参考にさせてもらいました。
SQLite 備忘録 - SQLite3 カラムの型を変更するを参照。
2.エンティティやDAOの変更
変更になったスキーマの情報をエンティティ側にも反映します。
必要であればDAOも修正します。
3.Databaseクラスのアノテーションでバージョン番号記載
RoomDatabaseを継承したクラスの@Databaseアノテーションで、versionの値をインクリメントします。 @Database(entities = {Test.class}, version = 2,exportSchema = true) public abstract class AppDatabase extends RoomDatabase { public abstract TestoDao testDao(); }
上記では version が1だったのを2にしました。
4.マイグレーションコードを記載し、DB作成時にaddMigrationsメソッドを追加
マイグレーションのためのSQLを記載するのですが、今回は上述の通りDBファイルをPC側で変更して差し替えます。
とはいえ、マイグレーションコードを書かないとRoomがエラーとなるため、メソッドは用意するものの、実装は空とします。
そして、Room.databaseBuilderで、マイグレーションコードを呼び出すようにします。z
//マイグレーションコード final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { //通常は以下にマイグレーションのSQLを記載するが、今回は空実装。 //database.execSQL("CREATE TABLE ..."); } }; //Room生成時に、上記マイグレーションコードをのメソッドを呼び出すようにする。 Room.databaseBuilder(context,AppDatabase.class, DBPATH) .setJournalMode(RoomDatabase.JournalMode.TRUNCATE) //SQLiteジャーナルモード:truncateモード。WALだとジャーナルファイルが残るため。 .addMigrations(MIGRATION_1_2) //ここでマイグレーションコードを実行 .build();
参考:
RoomでMigration #Android - Qiita
Roomのマイグレーションまとめ. Roomのマイグレーションについてまとめておきます。 | by Kenji Abe | Medium
Room データベースを移行する | Android Developers
【Androidアプリ開発】Room利用時のエラーと対処方法 | プログラミング・開発の備忘録
roomをmigrationする
Roomのマイグレーション | KINTO Tech Blog | キントテックブログ