アプリを起動する際に、特定のデータセットをすでに読み込んでいるデータベースを使用したい場合は、データベースを事前取り込みできます。Room では、API を使用して、初期化時にデバイスのファイル システム内にある事前パッケージ化済みデータベース ファイルの内容をデータベースに事前取り込みできます。
createFromAssetcreateFromFileアプリアセットから事前取り込みする
事前パッケージ化済みデータベース ファイルから Room データベースに事前取り込みする際、データベース ファイルがアプリの assets/ ディレクトリ内にある場合は、次のように createFromAsset 関数を RoomDatabase.Builder オブジェクトから呼び出してから、build を呼び出します。
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .build()
createFromAsset 関数は、assets/ ディレクトリから事前パッケージ化済みデータベース ファイルへの相対パスが入った文字列引数を受け付けます。
ファイル システムから事前取り込みする
事前パッケージ化済みデータベース ファイルから Room データベースに事前取り込みする際、データベース ファイルがデバイスのファイル システムでアプリの assets/ ディレクトリの外にある場合は、RoomDatabase.Builder オブジェクトから createFromFile 関数を呼び出してから、build を呼び出します。
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromFile(File("mypath")) .build()
createFromFile 関数は、File 引数を受け付けます。事前パッケージ化済みデータベース ファイルの
Room で指定されたファイルが直接開かれるのではなく、コピーが作成されるため、アプリにファイルの読み取り権限があることを確認してください。
事前パッケージ化済みデータベースを含む移行の処理
事前パッケージ化済みデータベース ファイルによって、Room データベースでのフォールバック移行の処理方法も変わります。通常、破壊的移行が有効で 、Room が移行パスなしで移行を実施する必要がある場合、Room はデータベース内のすべての テーブルを削除し、ターゲット バージョンの指定されたスキーマで空のデータベースを 作成します。ただし、ターゲット バージョンと同じ番号の事前パッケージ化済みデータベース ファイルを含めると、破壊的移行の実行後に、事前パッケージ化済みデータベース ファイルの内容が新規に再作成されたデータベースに取り込まれます。
Room データベースの移行の詳細については、 Room データベースを移行するをご覧ください。
以降のセクションでは、実際の動作の例を紹介します。
例: 事前パッケージ化済みデータベースを含むフォールバック移行
次の前提で説明します。
- バージョン 3 で Room データベースを定義している。
- デバイスにインストールされているデータベース インスタンスはバージョン 2 である。
- バージョン 3 の事前パッケージ化済みデータベース ファイルがある。
- バージョン 2 からバージョン 3 への移行パスは実装されていない。
- 破壊的移行が有効になっている。
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class FallbackAppDatabase : RoomDatabase() { // ... } fun createFallbackDb(appContext: Context) { Room.databaseBuilder<FallbackAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .fallbackToDestructiveMigration() .build() }
この状況では、次のようになります。
- アプリで定義されたデータベースがバージョン 3 で、デバイスにインストールされているデータベース インスタンスはバージョン 2 であるため、移行が必要です。
- バージョン 2 からバージョン 3 への移行プランが実装されていないため、この移行はフォールバック移行です。
fallbackToDestructiveMigrationビルダー 関数を呼び出すため、フォールバック移行は破壊的移行です。Room は、デバイスにインストールされているデータベース インスタンスを削除します。- バージョン 3 の事前パッケージ化済みデータベース ファイルがあるため、Room によってデータベースが再作成され、事前パッケージ化済みデータベース ファイルの内容が取り込まれます。事前パッケージ化済みデータベース ファイルがバージョン 2 の場合は、ターゲット バージョンと一致せず、フォールバック移行では使用されないことが通知されます。
例: 事前パッケージ化済みデータベースを含む実装済みの移行
次のように、バージョン 2 からバージョン 3 への移行パスを実装するとします。
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class ImplementedAppDatabase : RoomDatabase() { // ... } // Migration path definition from version 2 to version 3. val MIGRATION_2_3 = object : Migration(2, 3) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createImplementedDb(appContext: Context) { Room.databaseBuilder<ImplementedAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_2_3) .build() }
この状況では、次のようになります。
- アプリで定義されたデータベースがバージョン 3 で、デバイスにインストールされているデータベースはバージョン 2 であるため、移行が必要です。
- バージョン 2 からバージョン 3 への移行パスが実装されているため、
定義されている
migrate関数が実行され、すでにデータベースにあるデータを維持したまま、デバイス上のデータベース インスタンスがバージョン 3 に更新されます。フォールバック移行の場合にのみ事前パッケージ化済みデータベース ファイルが使用されるため、事前パッケージ化済みデータベース ファイルは使用されません。
例: 事前パッケージ化済みデータベースを含むマルチステップ移行
事前パッケージ化済みデータベース ファイルは、複数のステップで構成される移行にも影響します。次の場合を考えます。
- バージョン 4 で Room データベースを定義している。
- デバイスにインストールされているデータベース インスタンスはバージョン 2 である。
- バージョン 3 の事前パッケージ化済みデータベース ファイルがある。
- バージョン 3 からバージョン 4 への移行パスは実装されているが、バージョン 2 からバージョン 3 への移行パスは実装されていない。
- 破壊的移行が有効になっている。
// Database class definition declaring version 4. @Database(entities = [SampleEntity::class], version = 4) abstract class MultiStepAppDatabase : RoomDatabase() { // ... } val MIGRATION_3_4 = object : Migration(3, 4) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createMultiStepDb(appContext: Context) { Room.databaseBuilder<MultiStepAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_3_4) .fallbackToDestructiveMigration() .build() }
この状況では、次のようになります。
- アプリで定義されたデータベースがバージョン 4 で、デバイスにインストールされているデータベース インスタンスはバージョン 2 であるため、移行が必要です。
- バージョン 2 からバージョン 3 への移行パスが実装されていないため、この移行はフォールバック移行です。
fallbackToDestructiveMigrationビルダー 関数を呼び出すため、フォールバック移行は破壊的移行です。Room により、デバイス上のデータベース インスタンスが削除されます。- バージョン 3 の事前パッケージ化済みデータベース ファイルがあるため、Room によってデータベースが再作成され、事前パッケージ化済みデータベース ファイルの内容が取り込まれます。
- 現在、デバイスにインストールされているデータベースはバージョン 3 です。アプリで定義されているバージョンよりも低いため、別の移行が必要です。
- バージョン 3 からバージョン 4 への移行パスが実装されているため、
定義されている
migrate関数が実行され、バージョン 3 の事前パッケージ化済みデータベース ファイルから上書きコピーされたデータを維持したまま、デバイス上のデータベース インスタンスをバージョン 4 に更新します。