Android Official Database Room - Data Migration

Links to source documents

data migration

If app Adds / modifies feature s, it needs to redefine entity classes to reflect these changes. When the user updates, keep the original data, especially the data that cannot be recovered from the server.

Room allows you to write Migration classes for data migration. Each Migration class identifies startVersion and endVersioh. At runtime, Room runs the migrate() method in each Migration class to migrate data in the correct order

Note: If the necessary migrations are not provided, Room will rebuild the database, meaning that the previous data will be lost.

Room.databaseBuilder(getApplicationContext(), MyDb.class, "database-name")
        .addMigrations(MIGRATION_1_2, MIGRATION_2_3).build();

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
                + "`name` TEXT, PRIMARY KEY(`id`))");
    }
};

static final Migration MIGRATION_2_3 = new Migration(2, 3) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE Book "
                + " ADD COLUMN pub_year INTEGER");
    }
};

Note: To keep the migration logic running as expected, use full queries instead of referencing constants representing queries.

After the data migration is completed, Room verifies that the migration is correct and throws exceptional information if there is a problem.

Migration test

In order to ensure the stability of the application, data migration needs to be tested. Room provides a test warehouse. However, you need to export the database to work

Warehouse: android.arch.persistence.room:testing

export

Room will export the database information to the JSON file and need to set room.schemaLocation in build.gradle

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation":
                             "$projectDir/schemas".toString()]
            }
        }
    }
}

All exported JSON files should be saved so that Room can create older versions for testing

After adding test library dependencies, specify the JSON file location

android {
    ...
    sourceSets {
        androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
    }
}

Using Migration Test Helper to parse JSON files,

Test cases:

@RunWith(AndroidJUnit4.class)
public class MigrationTest {
    private static final String TEST_DB = "migration-test";

    @Rule
    public MigrationTestHelper helper;

    public MigrationTest() {
        helper = new MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
                MigrationDb.class.getCanonicalName(),
                new FrameworkSQLiteOpenHelperFactory());
    }

    @Test
    public void migrate1To2() throws IOException {
        SupportSQLiteDatabase db = helper.createDatabase(TEST_DB, 1);

        // db has schema version 1. insert some data using SQL queries.
        // You cannot use DAO classes because they expect the latest schema.
        db.execSQL(...);

        // Prepare for the next version.
        db.close();

        // Re-open the database with version 2 and provide
        // MIGRATION_1_2 as the migration process.
        db = helper.runMigrationsAndValidate(TEST_DB, 2, true, MIGRATION_1_2);

        // MigrationTestHelper automatically verifies the schema changes,
        // but you need to validate that the data was migrated properly.
    }
}

Keywords: Database JSON Android Gradle

Added by homchz on Sun, 19 May 2019 11:43:53 +0300