Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drop column Room migration android

I have a table Server

@Entity(tableName = "servers")
data class ServerDto(

    @PrimaryKey
    @ColumnInfo(name = "server_id")
    var serverId: Long,

    @ColumnInfo(name = "address", defaultValue = "")
    var serverAddress: String,

    @ColumnInfo(name = "description", defaultValue = "")
    var serverDescription: String,

    @ColumnInfo(name = "file_segment")
    var fileSegment: Int

) : Serializable

and a table accounts

@Entity(tableName = "accounts", primaryKeys = ["server_id", "account_id"])
data class AccountDto(

    @ColumnInfo(name = "server_id")
    val serverId: Long,

    @ColumnInfo(name = "account_id")
    val accountId: Int,

  @ColumnInfo(name = "username", defaultValue = "")
    val username: String,

    @ColumnInfo(name = "password", defaultValue = "")
    val password: String,

    @ColumnInfo(name = "first_name", defaultValue = "")
    var firstname: String,

    @ColumnInfo(name = "last_name", defaultValue = "")
    var lastname: String,

    @ColumnInfo(name = "email", defaultValue = "")
    var email: String,

    @ColumnInfo(name = "active")
    var active: Int

) : Serializable

I want to transfer 2 columns (username, password) from accounts to server and then remove them from accounts. I wrote the Migrations but i see that Android Studio does not allow to write DROP COLUMN since it underlines it with red. What is wrong with that??

override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE servers ADD COLUMN username VARCHAR")
        database.execSQL("ALTER TABLE servers ADD COLUMN password VARCHAR")
        database.execSQL("UPDATE servers SET username = (SELECT a.username FROM accounts a where a.server_id = servers.server_id and a.active = 1)")
        database.execSQL("UPDATE servers SET password = (SELECT a.password FROM accounts a where a.server_id = servers.server_id and a.active = 1)")
        database.execSQL("ALTER TABLE accounts ***DROP*** COLUMN username")
        database.execSQL("ALTER TABLE accounts ***DROP*** COLUMN password")
    }
like image 276
james04 Avatar asked Jan 31 '20 23:01

james04


People also ask

What is migration in Android?

Database migrationsA migration is performed on a database whenever it is necessary to update or revert that database's schema to some newer or older version. When a user updates to the latest version of your app, you don't want them to lose all of their existing data.

Why should I migrate from SQLite to room database in Android?

The Room persistence library provides a number of benefits over using the SQLite APIs directly: Compile-time verification of SQL queries. Convenience annotations that minimize repetitive and error-prone boilerplate code.

How do I delete data from a room database?

3.1 Add the Clear all data menu optionIn the Options menu, select Clear all data. All words should disappear. Restart the app. (Restart it from your device or the emulator; don't run it again from Android Studio) You should see the initial set of words.

How do I move a room DB?

As you add and change features in your app, you need to modify your Room entity classes and underlying database tables to reflect these changes. It is important to preserve user data that is already in the on-device database when an app update changes the database schema.


2 Answers

SQLite doesn't support column deletion straight away. You will have to do migration steps as follows: Source: https://www.sqlite.org/faq.html#q11

CREATE TABLE accounts_backup(serverId VARCHAR, accountId VARCHAR, firstname VARCHAR, lastname VARCHAR, email VARCHAR, active VARCHAR);

INSERT INTO accounts_backup SELECT serverId, accountId, firstname, lastname, email, active FROM accounts;

DROP TABLE accounts;

CREATE TABLE accounts(serverId VARCHAR, accountId VARCHAR, firstname VARCHAR, lastname VARCHAR, email VARCHAR, active VARCHAR);

INSERT INTO accounts SELECT serverId, accountId, firstname, lastname, email, active FROM accounts_backup;

DROP TABLE accounts_backup;
like image 61
Badhrinath Canessane Avatar answered Oct 22 '22 11:10

Badhrinath Canessane


Here's a combination of the previous two answers, written in Kotlin for Android:

private val MIGRATION_3_2 = object : Migration(3,2) {
        override fun migrate(database: SupportSQLiteDatabase) {
            //Drop column isn't supported by SQLite, so the data must manually be moved
            with(database) {
                execSQL("CREATE TABLE Users_Backup (id INTEGER, name TEXT, PRIMARY KEY (id))")
                execSQL("INSERT INTO Users_Backup SELECT id, name FROM Users")
                execSQL("DROP TABLE Users")
                execSQL("ALTER TABLE Users_Backup RENAME to Users")
            }
        }
    }
like image 5
Chris Sprague Avatar answered Oct 22 '22 11:10

Chris Sprague