简体   繁体   English

如何在下一版本的房间数据库Android中删除列?

[英]How to delete column in next version of room database Android?

How to delete a column in next version of room database android.DROp or delete not working.?如何删除下一版本的房间数据库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");
      }
  };

}

You have to do 4 steps:你必须做4个步骤:
1. Create the new table 1.创建新表
2. Copy the data 2.复制数据
3. Remove the old table 3.删除旧表
4. Change the table name to the correct one 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");
    }

};

The principle should still be the same, as you are using SQLite underneath Room.原理应该还是一样的,因为你在 Room 下使用 SQLite。 So you should be able to issue the same SQL statements described in that link.因此,您应该能够发出该链接中描述的相同 SQL 语句。 Have you tried?你有没有尝试过?

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");

Obviously change the table names and column names to suit your scenario.显然更改表名和列名以适合您的方案。

You can use a helper for doing table alterations like: Add, Delete, Rename or Change Scheme of a column.您可以使用助手进行表更改,例如:添加、删除、重命名或更改列的方案。

It handles the creation of a temp table, filling it with data, and deleting the old table.它处理临时表的创建、用数据填充和删除旧表。

Helper source code: https://gist.github.com/Benjiko99/23fbeee37d1d9f9a8b52ad21fc2585b9助手源码: 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
    )
}

My answer is very similar to what @Pedro Romao has given except that I have removed the extra unnecessary "NOT NULL" included in the sql statements.我的答案与@Pedro Romao 给出的答案非常相似,只是我删除了 sql 语句中包含的额外不必要的“NOT NULL”。 It should be added only where necessary as it might even cause an error where a column is allowed to be 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");

Thanks to @MrVasilev and @nobody special.感谢@MrVasilev 和@nobody 特别。 In my case I got an error during migration.就我而言,我在迁移过程中遇到错误。

I had to create the table with the exactly original structure by setting the column types, force NOT NULL and set the PRIMARY KEY.我必须通过设置列类型、强制 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")

Read the logs to understand whats wrong during migration:阅读日志以了解迁移过程中出了什么问题:

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=[]}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM