I exported a copy of the database from the emulator and moved the test database to an external file. This has been working well for sometime, however, today something changed and this error appeared.
Pre-packaged database has an invalid schema: tableLinkUserToPassword
Expected:
TableInfo
{
name='tableLinkUserToPassword',
columns = {
userId = Column { name='userId', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null' },
password = Column { name='password', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null' }
},
foreignKeys = [ForeignKey
{
referenceTable='tableUser', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[userId], referenceColumnNames=[userId]
}
],
indices = [Index { name='index_tableLinkUserToPassword_password', unique=false, columns=[password], orders=[ASC] },
Index { name='index_tableLinkUserToPassword_userId', unique=false, columns=[userId], orders=[ASC]}
]
}
Found:
TableInfo{name='tableLinkUserToPassword', columns={password=Column{name='password', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, userId=Column{name='userId', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}}, foreignKeys=[ForeignKey{referenceTable='tableUser', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[userId], referenceColumnNames=[userId]}], indices=[Index{name='index_tableLinkUserToPassword_userId', unique=false, columns=[userId], orders=[ASC]}, Index{name='index_tableLinkUserToPassword_password', unique=false, columns=[password], orders=[ASC]}]}
The UserId
and the Password
columns are switched in order. And notNull=false
seems not to match.
I have DB Browser but how would I change the order or columns?
Entity:
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
@Entity(
tableName = "tableLinkUserToPassword",
foreignKeys = [
ForeignKey(
entity = EntityUser::class,
parentColumns = ["userId"],
childColumns = ["userId"],
onDelete = ForeignKey.CASCADE
)
]
)
data class EntityLinkUserToPassword(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(index = true)
val userId: Int,
val password: String,
)
Thanks for any assistance
The order in which the columns appear is not an issue, it's the order in which they are extracted (I think). It is the reported values that matter.
However, what can be seen, as an example, is that the password column EXPECTED (what is extracted from the @Entity annotated class) has the NOT NULL
constraint (i.e. it must not be null) as per notNull=true
, whilst it found that there is no NOT NULL constraint coded for the password column in the FOUND (i.e. the pre-packaged database) as per notNull=false
.
So you either have to change the EntityLinkUserToPassword class to allow null, or change the pre-packaged database to have NOT NULL coded on the password column.
e.g. val password: String?,
You need to check ALL columns for discrepancies between the found and expected.
P.S. a second index on the userId column is a waste and inefficient. The PrimaryKey is an index. So there is no need for the @ColumnInfo
annotation.
However, again there is another discrepancy the second index on the pre-packaged database is on the password column. So you should have the @ColumnInfo
annotation moved to apply to the password val/column e.g. I believe that you want :-
data class EntityLinkUserToPassword(
@PrimaryKey(autoGenerate = true)
val userId: Int,
@ColumnInfo(index = true)
val password: String?,
)
I have DB Broswer but how would I chnage the order or columns?
You would/could :-
ALTER TABLE EntityLinkUserToPassword RENAME TO renamed_EntityLinkUserToPassword;
UPDATE renamed_EntityLinkUserToPassword SET password = 'a suitable default value' WHERE password IS NULL;
INSERT INTO EntityLinkUserToPassword SELECT * FROM renamed_EntityLinkUserToPassword ORDER BY userId ASC;
DROP TABLE IF EXISTS renamed_EntityLinkUserToPassword'
Getting the correct schema
createAllTables
method. The SQL for the creation of the tables is hard coded. Copy it and this will be the EXACT SQL.