【问题标题】:Query error to write migration with room database in Android在 Android 中使用房间数据库写入迁移的查询错误
【发布时间】:2020-06-13 04:59:42
【问题描述】:

我正在尝试在我的项目中迁移我的房间数据库,并为迁移编写查询。

在现有表上添加两个新列。这是代码。 这是对的吗?

private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE pages ADD COLUMN sources TEXT NOT NULL default '')");
    }
};

这里是 AppDatabase 代码:

@Database(entities = {DayInfoEntity.class, UserEntryEntity.class, CycleInfoEntity.class, CycleInfoTempEntity.class, PagesEntity.class}, version = 2, exportSchema = true)
@TypeConverters({DateConverter.class})
public abstract class AppDatabase extends RoomDatabase {

    private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE pages ADD COLUMN sources TEXT NOT NULL default ''");
        }
    };

    private static AppDatabase appDatabase;

    @VisibleForTesting
    private static final String DATABASE_NAME = "app_name";

    public abstract PagesDao pagesDao();

    private final MutableLiveData<Boolean> mIsDatabaseCreated = new MutableLiveData<>();

    public static AppDatabase getInstance(final Context context) {
        if (appDatabase == null) {
            synchronized (AppDatabase.class) {
                if (appDatabase == null) {
                    appDatabase = buildDatabase(context.getApplicationContext());
   appDatabase.updateDatabaseCreated(context.getApplicationContext());
                }
            }
        }
        return appDatabase;
    }

    private static AppDatabase buildDatabase(final Context appContext) {
        return Room.databaseBuilder(appContext, AppDatabase.class, DATABASE_NAME)
                .allowMainThreadQueries()
                .addMigrations(MIGRATION_1_2)
                .build();
    }

    private void updateDatabaseCreated(final Context context) {
        if (context.getDatabasePath(DATABASE_NAME).exists()) {
            setDatabaseCreated();
        }
    }

    private void setDatabaseCreated() {
        mIsDatabaseCreated.postValue(true);
    }
}

当时我尝试运行时出现此错误。

Migration didn't properly handle: pages.
 Expected:
TableInfo{name='pages', columns={help=Column{name='help', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, privacyPolicy=Column{name='privacyPolicy', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, legend=Column{name='legend', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, info=Column{name='info', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, backstory=Column{name='backstory', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, language=Column{name='language', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, termsConditions=Column{name='termsConditions', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, sources=Column{name='sources', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
 Found:
TableInfo{name='pages', columns={help=Column{name='help', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, legend=Column{name='legend', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, privacyPolicy=Column{name='privacyPolicy', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, info=Column{name='info', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, language=Column{name='language', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, sources=Column{name='sources', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue=''''}, termsConditions=Column{name='termsConditions', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}

【问题讨论】:

  • 从您编写的查询中删除)。它应该可以正常工作。
  • 请再次检查...

标签: android database sqlite android-room


【解决方案1】:

SQLite 不支持使用 单一的声明。要将多列添加到表中,您必须执行 多个 ALTER TABLE ADD COLUMN 语句。

https://www.sqltutorial.org/sql-add-column/

为每一列添加一个单独的语句:

  database.execSQL("ALTER TABLE pages ADD COLUMN sources TEXT NOT NULL default '' ");
  database.execSQL("ALTER TABLE pages ADD COLUMN backstory TEXT NOT NULL default '' ");

【讨论】:

  • 你能给我举个例子吗?因为找不到链接
  • 请检查我更新的问题,因为你告诉我的尝试一一我已经完成,我得到了这个错误。
  • 你更新实体类了吗?您还必须在那里添加新列。 @ColumnInfo(name="sources") @NonNull 私有字符串源;
【解决方案2】:

我通过更改波纹管代码解决了这个问题。不要忘记在数据库文件中添加这个fallbackToDestructiveMigration()

有关详细信息,请检查此链接并阅读一次。我知道这很无聊,但必须阅读。阅读详细信息后,我知道我的错误。 :)

这是链接 - https://developer.android.com/training/data-storage/room/migrating-db-versions

 private static AppDatabase buildDatabase(final Context appContext) {
    return Room.databaseBuilder(appContext, AppDatabase.class, DATABASE_NAME)
            .allowMainThreadQueries()
            .fallbackToDestructiveMigration() // ADD THIS WHILE YOU DOIGN MIGRATION
            .addMigrations(MIGRATION_1_2)
            .build();
}

【讨论】:

  • 这将删除表中的旧数据。
猜你喜欢
  • 1970-01-01
  • 2021-08-13
  • 2018-05-13
  • 2019-02-13
  • 2020-11-28
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
相关资源
最近更新 更多