当前位置: 首页 > 知识库问答 >
问题:

仅添加新表时的Room数据库迁移

路雅懿
2023-03-14
@Database(entities = {User.class}, version = 1)
abstract class AppDatabase extends RoomDatabase {
    public abstract Dao getDao();
}
@Database(entities = {User.class, Pet.class}, version = 2)
abstract class AppDatabase extends RoomDatabase {
    public abstract Dao getDao();
}
final Migration MIGRATION_1_2 =
        new Migration(1, 2) {
            @Override
            public void migrate(@NonNull final SupportSQLiteDatabase database) {
                database.execSQL("CREATE TABLE IF NOT EXISTS `Pet` (`name` TEXT NOT NULL, PRIMARY KEY(`name`))");
            }
        };

然而,我发现手动操作很不方便。有没有办法告诉Room:我不会接触任何现有的表,所以数据是安全的。请为我创建迁移?

共有1个答案

金和雅
2023-03-14

Room没有一个好的迁移系统,至少在2.1.0-alpha03之前没有。

因此,在我们有更好的迁移系统之前,有一些变通方法可以在房间中进行轻松的迁移。

由于不存在@database(createNewTables=true)migrationsystem.createTable(user::class)这样的方法,所以唯一可能的方法是运行

CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))
val MIGRATION_1_2 = object : Migration(1, 2){
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))")
    }
}
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
   //...
}
kapt {
    arguments {
        arg("room.schemaLocation", "$projectDir/schemas".toString())
    }
} 
  "formatVersion": 1,
  "database": {
    "version": 2,
    "identityHash": "325bd539353db508c5248423a1c88c03",
    "entities": [
      {
        "tableName": "User",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, PRIMARY KEY(`id`))",
        "fields": [
          {
            "fieldPath": "id",
            "columnName": "id",
            "affinity": "INTEGER",
            "notNull": true
          },

因此,您可以在migrate方法中包含上面的createsql

如果您不想导出模式,仍然可以通过运行或构建将生成appdatabase_impl.java文件的项目来获得查询。并且可以在指定的文件中。

@Override
public void createAllTables(SupportSQLiteDatabase _db) {
  _db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))");

createalltables方法中,将有所有实体的创建脚本。您可以获取它并将其包含在migrate方法中。

kapt "androidx.room:room-compiler:$room_version"
    null
public final class UserSqlUtils {
  public String createTable = "CREATE TABLE IF NOT EXISTS User (id INTEGER, PRIMARY KEY(id))";
}
val MIGRATION_1_2 = object : Migration(1, 2){
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL(UserSqlUtils().createTable)
    }
}

使用RoomExtension的应用程序

希望有用。

在撰写本答案时,room版本为2.1.0-alpha03,当我给开发人员发邮件时,得到的回复是

 类似资料:
  • 问题内容: 假设我有一个简单的Room数据库: 现在,我要添加一个新实体:并将版本增加到2: 当然,Room会引发异常: 假设我没有更改类(因此所有数据都是安全的),我必须提供仅创建一个新表的迁移。因此,我正在研究Room生成的类,搜索生成的查询以创建我的新表,将其复制并粘贴到迁移中: 但是,我发现手动进行操作很不方便。有没有办法告诉Room: 我没有触摸任何现有表,因此数据是安全的。 请为我创建

  • 通过提供从3到4的迁移,我正在将我的数据库从版本3升级到版本4。 找到:TableInfo{name='posts',Columns={imageWidth=Column{name='image widt',Type='integer',affinity='3',notnull=true,PrimaryKeyPosition=0},authorImageLocalURL=Column{name='

  • 我需要在我的laravel项目中添加一个新列,这没有问题,我使用了进行了更新,一切正常。现在我需要找出这个表上有多少条记录,并用一些值进行更新。 我有表: 因此,我使用新的迁移文件创建了新字段: 现在我需要用一些值更新表中的这个字段,例如,如果表中有100条记录,那么我需要在每一行中插入值“carry-X”,其中X是一个从1到100的数字。例如: 逮捕令-1,逮捕令-2,......逮捕证-100

  • 我有致命的异常:java.lang.RuntimeException:计算数据库实时数据时出现异常。在崩溃报告中 为什么TableInfo中的所有内容都是空的 谁能帮我一下,我真的不知道我做错了什么或者是不是一个bug。

  • 我在Laravel4.2项目中工作,现在我想在现有的表用户中添加列。现在我想添加另一列,当我运行migration命令时,我总是收到相同的消息“无需迁移”下面是我的迁移模式代码 我在终点站跑步 我还运行以下命令 但是当我运行上面的命令时,我收到以下错误 SQLSTATE[42S01]:基表或视图已经存在: 1050表'用户'已经存在

  • 预期: 找到TableInfo{name='user',Columns={name=Column{name='name',Type='text',NotNull=False,PrimaryKeyPosition=0},Age=Column{name='Age',Type='integer',NotNull=True,PrimaryKeyPosition=0},ID=Column{name='id'