首页 > 解决方案 > android.database.sqlite.SQLiteException: no such column: id (code 1 SQLITE_ERROR): , 同时从旧版本的 db 编译到新版本

问题描述

@Database(entities = {HoroscopeResponse.class, HoroscopeData.class, EmojiBean.class, DailyHoroscopeTimeStamp.class, WeeklyHoroscopeTimeStamp.class
        , MonthlyHoroscopeTimeStamp.class, YearlyHoroscopeTimeStamp.class}, version = 4, exportSchema = false)
public abstract class HoroscopeDatabase extends RoomDatabase {
    private static final String LOG_TAG = "Horoscope_database";

    private static final Object LOCK = new Object();
    private static final String DATABASE_NAME = "horoscope_database";
    private static HoroscopeDatabase sInstance;

    public static HoroscopeDatabase getInstance(Context context) {
        if (sInstance == null) {
            synchronized (LOCK) {
                Migration migration2_3 = new Migration(2,3) {
                    @Override
                    public void migrate(@NonNull SupportSQLiteDatabase database) {
                        database.execSQL("CREATE TABLE IF NOT EXISTS 'emoji_table' ('date' INTEGER NOT NULL,'emoji' INTEGER NOT NULL, 'month' TEXT NOT NULL,'year' TEXT NOT NULL,'day' TEXT NOT NULL,'beanpos' INTEGER NOT NULL, PRIMARY KEY ('id') ); ");
                    }
                };
                Migration migration1_2 = new Migration(1,2) {
                    @Override
                    public void migrate(@NonNull SupportSQLiteDatabase database) {
                        database.execSQL("ALTER TABLE 'horoscope_data' ADD COLUMN'rashiDescriptionEng' TEXT DEFAULT ''");
                    }
                };
                Migration migration3_4 = new Migration(3,4) {
                    @Override
                    public void migrate(@NonNull SupportSQLiteDatabase database) {
                        database.execSQL("ALTER TABLE 'emoji_table' RENAME COLUMN 'id' TO '_id'");
                    }
                };
                Log.d(LOG_TAG, "Creating new database instance");
                sInstance = Room.databaseBuilder(context.getApplicationContext(),
                        HoroscopeDatabase.class, HoroscopeDatabase.DATABASE_NAME)
                        .addMigrations(migration1_2)
                        .addMigrations(migration2_3)
                        .addMigrations(migration3_4)
                        .allowMainThreadQueries()
                        .build();
            }
        }
        Log.d(LOG_TAG, "Getting the database instance");
        return sInstance;
    }

}

我在迁移 1_2 中创建 emoji_table 时出现错误(用于从旧的 db 应用程序版本迁移,否则很好)无法启动活动 ComponentInfo{MainActivity}:android.database.sqlite.SQLiteException:没有这样的列:id(代码 1 SQLITE_ERROR) : , 编译时: CREATE TABLE IF NOT EXISTS 'emoji_table'

标签: androidsqliteandroid-room

解决方案


错误正如它所说的那样。那就是你有: -

CREATE TABLE IF NOT EXISTS 'emoji_table' ('date' INTEGER NOT NULL,'emoji' INTEGER NOT NULL, 'month' TEXT NOT NULL,'year' TEXT NOT NULL,'day' TEXT NOT NULL,'beanpos' INTEGER NOT NULL, PRIMARY KEY ('id') ); 

并且没有id列可以用作主键。

相反,您想要/需要类似的东西:-

CREATE TABLE IF NOT EXISTS 'emoji_table' ('id' INTEGER, 'date' INTEGER NOT NULL,'emoji' INTEGER NOT NULL, 'month' TEXT NOT NULL,'year' TEXT NOT NULL,'day' TEXT NOT NULL,'beanpos' INTEGER NOT NULL, PRIMARY KEY ('id') ); 

使用 Room 实体规则,因此您需要确保EmojiBean.class(我假设这是正确的实体)确实具有id的字段/变量,尽管当您将迁移 3 到 4 中的列重命名时,字段/变量应该是_id或有一个命名列 _id 的 @ColumnInfo 注释)。


推荐阅读