首页 > 解决方案 > 房间迁移未找到表格列

问题描述

我想从我的 sqlite 数据库中的表中删除一些列。我创建了一个新表(使用不同的名称),将旧表中的适当数据插入到新表中。然后我删除了旧表并将新表重命名为旧表的名称。但是我收到了这个错误

 Caused by: java.lang.IllegalStateException: Migration didn't properly handle: Clothes(com.dayaramo.wearyourcloset.Objects.ClothingItem).
     Expected:
    TableInfo{name='Clothes', columns={season=Column{name='season', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, item=Column{name='item', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, wornCount=Column{name='wornCount', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, category=Column{name='category', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, photoPath=Column{name='photoPath', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
     Found:
    TableInfo{name='Clothes', columns={}, foreignKeys=[], indices=[]}

我的 Clothing 类已更改以反映我删除的列,但我不确定为什么找不到这些列

服装类

@Entity(tableName = "Clothes")
public class ClothingItem implements Parcelable {

    @PrimaryKey(autoGenerate = true)
    private long id;
    private String item;
    private String season;
    private String category;
    private int wornCount;
    private String photoPath;



    public static final Creator<ClothingItem> CREATOR = new Creator<ClothingItem>() {
        @Override
        public ClothingItem createFromParcel(Parcel in) {
            return new ClothingItem(in);
        }

        @Override
        public ClothingItem[] newArray(int size) {
            return new ClothingItem[size];
        }
    };

    public void setId(long id) {
        this.id = id;
    }

    public void setItem(String item) {
        this.item = item;
    }

    public void setSeason(String season) {
        this.season = season;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public void setPhotoPath(String photoPath) {
        this.photoPath = photoPath;
    }


    public void setWornCount(int wornCount) { this.wornCount = wornCount; }

    @Ignore
    public ClothingItem(String item, String season, String category, int wornCount) {
        this.item = item;
        this.season = season;
        this.category = category;
        this.wornCount = wornCount;
    }

    public ClothingItem(String item, String season, String category, int wornCount, String photoPath) {
        this.item = item;
        this.season = season;
        this.category = category;
        this.wornCount = wornCount;
        this.photoPath = photoPath;
    }

    @Ignore
    public ClothingItem() {
    }

    public String getItem() {
        return item;
    }

    public String getCategory() {
        return category;
    }

    public String getSeason() {
        return season;
    }

    public String getPhotoPath() {
        return photoPath;
    }


    public long getId() {return id; }

    public int getWornCount() { return wornCount; }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(id);
        dest.writeString(item);
        dest.writeString(season);
        dest.writeString(category);
        dest.writeInt(wornCount);
        dest.writeString(photoPath);
    }

    protected ClothingItem(Parcel in) {
        id = in.readLong();
        item = in.readString();
        season = in.readString();
        category = in.readString();
        wornCount = in.readInt();
        photoPath = in.readString();
    }
}

迁移代码

@Database(entities = {ClothingItem.class, DailyOutfit.class}, version = 14)
public abstract class ClothingItemDatabase extends RoomDatabase {

    public abstract ClothingDao clothingDao();
//    public abstract OutfitDao outfitDao();
    public abstract DailyOutfitDao dailyOutfitDao();

    private static volatile ClothingItemDatabase INSTANCE;
    private static final Object sLock = new Object();

....
 static final Migration MIGRATION_12_13 = new Migration(12,13) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {

            database.execSQL("CREATE TABLE `ClothingItems` (`id` INTEGER PRIMARY KEY AUTOINCREMENT," +
                    "`item` TEXT, `season` TEXT, `category` TEXT, `wornCount` INTEGER, `photoPath` TEXT)");

            database.execSQL("INSERT INTO `ClothingItems` (`id`,`item`, `season`,`category`,`wornCount`,`photoPath`)" +
                    "SELECT `id`,`item`, `season`,`category`,`wornCount`,`photoPath` from Clothes");

        }
    };

    static final Migration MIGRATION_13_14 = new Migration(13,14) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {

            database.execSQL("DELETE FROM `Clothes`");
            database.execSQL("DROP TABLE `Clothes`");
        }
    };


    static final Migration MIGRATION_14_15 = new Migration(14, 15) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {

            database.execSQL("DELETE FROM `DailyOutfits`");

        }
    };

 static final Migration MIGRATION_15_16 = new Migration(15, 16) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {

//            database.execSQL("DROP TABLE `Outfits`");
        }
    };



    static  ClothingItemDatabase getDatabase(final Context context) {

        if (INSTANCE == null) {

            synchronized (ClothingItemDatabase.class) {
                if (INSTANCE == null) {

                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            ClothingItemDatabase.class, "Clothes")
                            .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4,MIGRATION_4_5,MIGRATION_5_6,MIGRATION_6_7
                                    ,MIGRATION_8_9,MIGRATION_9_10, MIGRATION_10_11,MIGRATION_11_12,MIGRATION_12_13,MIGRATION_13_14,MIGRATION_14_15,MIGRATION_15_16)
                            .addCallback(sRoomDatabaseCallback).build();
                }
            }
        }

        return INSTANCE;
    }
//    MIGRATION_7_8, MIGRATION_8_9, MIGRATION_9_10)

    private static Callback sRoomDatabaseCallback = new Callback() {

        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            super.onOpen(db);
        }
    };


    /*
     * Migrate from:
     * version 1 - using the SQLiteDatabase API
     * to
     * version 2 - using Room
     * November 12,2019
     * Migrate from:
     * version 3 - using the SQLiteDatabase API
     * to
     * version 4 - using Room
     * March 19, 2020
     *to
     * version 5
     * May 3, 2020
     *to
     *version 5,6,7
     * May 3, 2020
     */


    public static ClothingItemDatabase getInstance(Context context) {
        synchronized (sLock) {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                        ClothingItemDatabase.class, "ClothingItem.db")
                        .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4,MIGRATION_4_5,MIGRATION_5_6,
                                MIGRATION_6_7,MIGRATION_8_9,MIGRATION_9_10,MIGRATION_10_11, MIGRATION_11_12,MIGRATION_12_13,MIGRATION_13_14,MIGRATION_14_15,MIGRATION_15_16)
                        .fallbackToDestructiveMigration()
                        .build();
            }
            return INSTANCE;
        }
    }
}


标签: androidsqliteandroid-studioandroid-roomdatabase-migration

解决方案


经过大量研究后,我从Lua Software Code中找到了答案,我意识到我没有在我的数据库类中使用 exportSchema。

@Database(entities = {ClothingItem.class, DailyOutfit.class}, version = 15,exportSchema = true)

每次添加迁移时,它都会在 assets 文件夹下创建一个 JSON,这样您就可以看到 SQL 命令发生了什么一旦我添加了它并在没有运行它的情况下构建了项目,我可以看到表是如何创建的。事实证明,我的一个专栏已更改为“Not Null”,这就是导致错误的原因。


推荐阅读