在 Android 中使用房间数据库写入迁移的查询错误

Posted

技术标签:

【中文标题】在 Android 中使用房间数据库写入迁移的查询错误【英文标题】:Query error to write migration with room database in 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:
TableInfoname='pages', columns=help=Columnname='help', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', privacyPolicy=Columnname='privacyPolicy', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', legend=Columnname='legend', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', info=Columnname='info', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', id=Columnname='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null', backstory=Columnname='backstory', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', language=Columnname='language', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null', termsConditions=Columnname='termsConditions', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', sources=Columnname='sources', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', foreignKeys=[], indices=[]
 Found:
TableInfoname='pages', columns=help=Columnname='help', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', legend=Columnname='legend', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', privacyPolicy=Columnname='privacyPolicy', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', info=Columnname='info', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', id=Columnname='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null', language=Columnname='language', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null', sources=Columnname='sources', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='''', termsConditions=Columnname='termsConditions', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null', foreignKeys=[], indices=[]

【问题讨论】:

从您编写的查询中删除)。它应该可以正常工作。 请再次检查... 【参考方案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();

【讨论】:

这将删除表中的旧数据。

以上是关于在 Android 中使用房间数据库写入迁移的查询错误的主要内容,如果未能解决你的问题,请参考以下文章

生成 Android 房间迁移的最佳方法是啥?

Android房间迁移null错误

Android房间迁移添加枚举列表

(Android) 房间数据库迁移不会改变数据库

迁移房间数据库时有没有办法使用迁移期间计算的变量?

Android 房间迁移测试失败,但没有任何改变