如何在Android会议室数据库的下一版本中删除列?

时间:2018-09-08 12:07:42

标签: android android-room

如何在房间数据库android.DROp的下一版本中删除列或删除不起作用??

@Database(entities = {User.class, AdTime.class}, version = 1, exportSchema = false)
  public abstract class AppDataBase extends RoomDatabase {

  private static AppDataBase INSTANCE;

  public abstract UserDao userModel();

  public abstract AdDao adModel();

  public static AppDataBase getInMemoryDatabase(Context context) {

    if (INSTANCE == null) {
        INSTANCE = Room.databaseBuilder(context, AppDataBase.class, "adrider")
                // To simplify the codelab, allow queries on the main thread.
                // Don't do this on a real app! See PersistenceBasicSample for an example.
                .allowMainThreadQueries()
              //  .addMigrations(MIGRATION_1_2)
                //  .fallbackToDestructiveMigration()
                .build();
      }
      return INSTANCE;
    }

  static final Migration MIGRATION_1_2=new Migration(1,2) {
      @Override
      public void migrate(@NonNull SupportSQLiteDatabase database) {
          database.execSQL("ALTER TABLE User "
                + "DROP Download");
      }
  };

}

5 个答案:

答案 0 :(得分:3)

原理仍然是相同的,因为您在Room下面使用SQLite。因此,您应该能够发出该链接中描述的相同SQL语句。你尝试过吗?

database.execSQL("CREATE TABLE t1_backup AS SELECT a, b FROM t1");
database.execSQL("DROP TABLE t1");
database.execSQL("ALTER TABLE t1_backup RENAME TO t1");

显然,要根据您的情况更改表名和列名。

答案 1 :(得分:3)

您必须执行4个步骤: 1.创建新表 2.复制数据 3.删除旧表 4.将表名称更改为正确的名称

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
    // Create the new table
    database.execSQL(
            "CREATE TABLE users_new (userid TEXT, username TEXT, last_update INTEGER, 
    PRIMARY KEY(userid))");
    // Copy the data
    database.execSQL(
            "INSERT INTO users_new (userid, username, last_update) SELECT userid, 
    username, last_update FROM users");
    // Remove the old table
    database.execSQL("DROP TABLE users");
    // Change the table name to the correct one
    database.execSQL("ALTER TABLE users_new RENAME TO users");
    }
};

答案 2 :(得分:1)

您可以使用助手来进行表格更改,例如:添加,删除,重命名或更改列的方案。

它处理临时表的创建,向其中填充数据并删除旧表。

Helper源代码:https://gist.github.com/Benjiko99/23fbeee37d1d9f9a8b52ad21fc2585b9

fun alterTableUsage(database: SupportSQLiteDatabase) {
    DbMigrationsHelper.alterTable(
        db = database,
        tableName = "Reservations",
        columns = mapOf(
            "id INTEGER".toExisting(), // Retains without changes
            "title TEXT".toExisting("name"), // Renames column "name" to "title"
            "description TEXT".toNothing(), // Adds a new column
            "creatorId INTEGER NOT NULL".toExisting() // Change scheme from "creatorId INTEGER" and add "NON NULL"
            // Any columns that existed in the "Reservations" table
            // and aren't specified in this map will be removed
        ),
        primaryKeys = listOf("id") // Add more than one key to create a compound primary key
    )
}

答案 3 :(得分:0)

感谢@MrVasilev和@nobody special。 就我而言,在迁移过程中出现错误。

我必须通过设置列类型,强制NOT NULL和设置PRIMARY KEY来创建具有完全原始结构的表。

database.execSQL("CREATE TABLE backup_table (id INTEGER PRIMARY KEY NOT NULL, title TEXT NOT NULL, account TEXT NOT NULL, hash TEXT NOT NULL, sequence INTEGER NOT NULL)")
database.execSQL("INSERT INTO table_backup(id, title, account, hash, sequence) SELECT id, title, account, hash, sequence FROM original_table")
database.execSQL("DROP TABLE original_table")
database.execSQL("ALTER TABLE backup_table RENAME TO original_table")

阅读日志以了解迁移期间出了什么问题:

Migration didn't properly handle 

Expected: TableInfo{name='my_table', columns={sequence=Column{name='sequence', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1}, title=Column{name='title', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0}, account=Column{name='account', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0}, hash=Column{name='hash', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0}}, foreignKeys=[], indices=[]} 

Found: TableInfo{name='my_table', columns={sequence=Column{name='sequence', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1}, title=Column{name='title', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0}, account=Column{name='account', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0}, hash=Column{name='hash', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0}}, foreignKeys=[], indices=[]}

答案 4 :(得分:0)

我的答案与@Pedro Romao给出的答案非常相似,只是我删除了sql语句中包含的多余不必要的“ NOT NULL”。仅应在必要时添加它,否则在允许列为Null的情况下甚至可能导致错误。

    // Create a table that would be your new table. Specify the type of each field and include NON NULL when field can't be null for example in the case of a primary key
    database.execSQL("CREATE TABLE Users_backup (id INTEGER NOT NULL, name TEXT, PRIMARY KEY(id))"); 
    // Copy the desired columns from the old table into this new table
    database.execSQL("INSERT INTO Users_backup (id, name) SELECT id, name FROM Users");
    // Delete the old table
    database.execSQL("DROP TABLE Users");
    // Rename the new table to the old table's name so that the rest of your code can recognize this table as the former one.
    database.execSQL("ALTER TABLE Users_backup RENAME TO Users");