房间迁移 - 将 INTEGER 列类型更改为可为空 (SQLITE)
Room Migration - Change INTEGER column type to nullable (SQLLITE)
我有一个带有 int 列的版本 1 数据库。
在版本 2 中,我想让我的列可以为空,为了实现这一点,我在我的 java 实体 class.
中将我的列数据类型从 int 更改为 Integer
经过一些研究后,我意识到不可能只更改列的数据类型。
这是我在迁移方法中所做的:
我原来的实体名称是 TaskEntity,我正在创建一个新的临时 table,复制数据然后删除原来的 table 然后将临时 table 重命名为原来的 table。
database.execSQL(
"BEGIN TRANSACTION;" +
"CREATE TABLE TaskEntityNew('id' INTEGER PRIMARY KEY AUTOINCREMENT," +
"'text' TEXT," +
"'caseid' INTEGER NULL," +
"'status' INTEGER NOT NULL DEFAULT 0," +
"'datetime' DATETIME," +
",'updateDt' DATETIME," +
" FOREIGN KEY (caseid) REFERENCES CaseEntity(id));" +
"INSERT INTO TaskEntityNew(text,caseid,status,datetime,updateDt) SELECT text,caseid,status,datetime,update FROM TaskEntity;"+
"DROP TABLE TaskEntity;" +
"ALTER TABLE 'TaskEntityNew' RENAME TO 'TaskEntity';" +
"COMMIT;"
);
但是我收到这个错误
Caused by: java.lang.IllegalStateException: Migration didn't properly handle TaskEntity(EntityCollection.TaskEntity).
Expected:
TableInfo{name='TaskEntity', columns={text=Column{name='text', type='TEXT', notNull=false, primaryKeyPosition=0}, updateDt=Column{name='updateDt', type='INTEGER', notNull=false, primaryKeyPosition=0}, datetime=Column{name='datetime', type='INTEGER', notNull=false, primaryKeyPosition=0}, status=Column{name='status', type='INTEGER', notNull=true, primaryKeyPosition=0}, caseid=Column{name='caseid', type='INTEGER', notNull=false, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=1}}, foreignKeys=[ForeignKey{referenceTable='CaseEntity', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[caseid], referenceColumnNames=[id]}], indices=[Index{name='index_TaskEntity_caseid', unique=false, columns=[caseid]}]}
Found:
TableInfo{name='TaskEntity', columns={text=Column{name='text', type='TEXT', notNull=false, primaryKeyPosition=0}, updateDt=Column{name='updateDt', type='INTEGER', notNull=false, primaryKeyPosition=0}, datetime=Column{name='datetime', type='INTEGER', notNull=false, primaryKeyPosition=0}, status=Column{name='status', type='INTEGER', notNull=true, primaryKeyPosition=0}, caseid=Column{name='caseid', type='INTEGER', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=1}}, foreignKeys=[ForeignKey{referenceTable='CaseEntity', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[caseid], referenceColumnNames=[id]}], indices=[Index{name='index_TaskEntity_caseid', unique=false, columns=[caseid]}]}
我能想到的一个问题是我的 SQL 块没有执行,我的旧 table 数据试图与旧的 java 实体匹配 class.
任何帮助将不胜感激!
根据文档,execSQL
只执行一个 SQL 语句:
the SQL statement to be executed. Multiple statements separated by semicolons are not supported.
因此您需要将代码重写为多个调用,例如:
database.execSQL("BEGIN TRANSACTION;");
database.execSQL("CREATE TABLE TaskEntityNew('id' INTEGER PRIMARY KEY AUTOINCREMENT," +
"'text' TEXT," +
"'caseid' INTEGER NULL," +
"'status' INTEGER NOT NULL DEFAULT 0," +
"'datetime' DATETIME," +
",'updateDt' DATETIME," +
" FOREIGN KEY (caseid) REFERENCES CaseEntity(id));");
database.execSQL("INSERT INTO TaskEntityNew(text,caseid,status,datetime,updateDt) SELECT text,caseid,status,datetime,update FROM TaskEntity;");
database.execSQL("DROP TABLE TaskEntity;");
database.execSQL("ALTER TABLE 'TaskEntityNew' RENAME TO 'TaskEntity';");
database.execSQL("COMMIT;");
按原样,SQLite 正在执行 "BEGIN TRANSACTION;" 然后忽略其余的 SQL 语句。
我有一个带有 int 列的版本 1 数据库。 在版本 2 中,我想让我的列可以为空,为了实现这一点,我在我的 java 实体 class.
中将我的列数据类型从 int 更改为 Integer经过一些研究后,我意识到不可能只更改列的数据类型。
这是我在迁移方法中所做的:
我原来的实体名称是 TaskEntity,我正在创建一个新的临时 table,复制数据然后删除原来的 table 然后将临时 table 重命名为原来的 table。
database.execSQL(
"BEGIN TRANSACTION;" +
"CREATE TABLE TaskEntityNew('id' INTEGER PRIMARY KEY AUTOINCREMENT," +
"'text' TEXT," +
"'caseid' INTEGER NULL," +
"'status' INTEGER NOT NULL DEFAULT 0," +
"'datetime' DATETIME," +
",'updateDt' DATETIME," +
" FOREIGN KEY (caseid) REFERENCES CaseEntity(id));" +
"INSERT INTO TaskEntityNew(text,caseid,status,datetime,updateDt) SELECT text,caseid,status,datetime,update FROM TaskEntity;"+
"DROP TABLE TaskEntity;" +
"ALTER TABLE 'TaskEntityNew' RENAME TO 'TaskEntity';" +
"COMMIT;"
);
但是我收到这个错误
Caused by: java.lang.IllegalStateException: Migration didn't properly handle TaskEntity(EntityCollection.TaskEntity).
Expected:
TableInfo{name='TaskEntity', columns={text=Column{name='text', type='TEXT', notNull=false, primaryKeyPosition=0}, updateDt=Column{name='updateDt', type='INTEGER', notNull=false, primaryKeyPosition=0}, datetime=Column{name='datetime', type='INTEGER', notNull=false, primaryKeyPosition=0}, status=Column{name='status', type='INTEGER', notNull=true, primaryKeyPosition=0}, caseid=Column{name='caseid', type='INTEGER', notNull=false, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=1}}, foreignKeys=[ForeignKey{referenceTable='CaseEntity', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[caseid], referenceColumnNames=[id]}], indices=[Index{name='index_TaskEntity_caseid', unique=false, columns=[caseid]}]}
Found:
TableInfo{name='TaskEntity', columns={text=Column{name='text', type='TEXT', notNull=false, primaryKeyPosition=0}, updateDt=Column{name='updateDt', type='INTEGER', notNull=false, primaryKeyPosition=0}, datetime=Column{name='datetime', type='INTEGER', notNull=false, primaryKeyPosition=0}, status=Column{name='status', type='INTEGER', notNull=true, primaryKeyPosition=0}, caseid=Column{name='caseid', type='INTEGER', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', notNull=true, primaryKeyPosition=1}}, foreignKeys=[ForeignKey{referenceTable='CaseEntity', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[caseid], referenceColumnNames=[id]}], indices=[Index{name='index_TaskEntity_caseid', unique=false, columns=[caseid]}]}
我能想到的一个问题是我的 SQL 块没有执行,我的旧 table 数据试图与旧的 java 实体匹配 class. 任何帮助将不胜感激!
根据文档,execSQL
只执行一个 SQL 语句:
the SQL statement to be executed. Multiple statements separated by semicolons are not supported.
因此您需要将代码重写为多个调用,例如:
database.execSQL("BEGIN TRANSACTION;");
database.execSQL("CREATE TABLE TaskEntityNew('id' INTEGER PRIMARY KEY AUTOINCREMENT," +
"'text' TEXT," +
"'caseid' INTEGER NULL," +
"'status' INTEGER NOT NULL DEFAULT 0," +
"'datetime' DATETIME," +
",'updateDt' DATETIME," +
" FOREIGN KEY (caseid) REFERENCES CaseEntity(id));");
database.execSQL("INSERT INTO TaskEntityNew(text,caseid,status,datetime,updateDt) SELECT text,caseid,status,datetime,update FROM TaskEntity;");
database.execSQL("DROP TABLE TaskEntity;");
database.execSQL("ALTER TABLE 'TaskEntityNew' RENAME TO 'TaskEntity';");
database.execSQL("COMMIT;");
按原样,SQLite 正在执行 "BEGIN TRANSACTION;" 然后忽略其余的 SQL 语句。