我在本地计算机上创建了一个数据库,将其预填充到Room中。数据库位于Windows计算机的本地MySQL中。但是,我使用了Room的SQL语句来创建它,并且由于不同的方言,只做了一些小的更改。因此,该方案与设想的是一样的。然而,问题是,当我将其转换为SQLite时,转换器不关心大小写,并以小写书写所有表名。(因为MySQL-Database对表名不区分大小写。)这将导致Android中的数据库方案无效,因为外键中的表名是小写的,而不是以大写字母开头。这是没有格式化的错误消息(因为它显示的很明显,实际上没有区别):
java.lang.IllegalStateException: Pre-packaged database has an invalid schema: Strengths(bi.deutsch_kirundi_app.db.entities.germanSpecificTables.Strengths).
Expected:
TableInfo{name='Strengths', columns={name=Column{name='name', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, singularStrength=Column{name='singularStrength', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, pluralStrength=Column{name='pluralStrength', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[ForeignKey{referenceTable='Strengths', onDelete='NO ACTION', onUpdate='NO ACTION', columnNames=[singularStrength], referenceColumnNames=[id]}, ForeignKey{referenceTable='Strengths', onDelete='NO ACTION', onUpdate='NO ACTION', columnNames=[pluralStrength], referenceColumnNames=[id]}], indices=[Index{name='index_Strengths_singularStrength', unique=false, columns=[singularStrength]}, Index{name='index_Strengths_pluralStrength', unique=false, columns=[pluralStrength]}]}
Found:
TableInfo{name='Strengths', columns={name=Column{name='name', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, singularStrength=Column{name='singularStrength', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, pluralStrength=Column{name='pluralStrength', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[ForeignKey{referenceTable='strengths', onDelete='NO ACTION', onUpdate='NO ACTION', columnNames=[pluralStrength], referenceColumnNames=[id]}, ForeignKey{referenceTable='strengths', onDelete='NO ACTION', onUpdate='NO ACTION', columnNames=[singularStrength], referenceColumnNames=[id]}], indices=[Index{name='index_Strengths_singularStrength', unique=false, columns=[singularStrength]}, Index{name='index_Strengths_pluralStrength', unique=false, columns=[pluralStrength]}]}
格式如下:
Expected:
TableInfo{
name='Strengths',
columns={
name=Column{name='name', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'},
singularStrength=Column{name='singularStrength', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0,
defaultValue='null'},
id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'},
pluralStrength=Column{name='pluralStrength', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0,
defaultValue='null'}},
foreignKeys=[
ForeignKey{referenceTable='Strengths', onDelete='NO ACTION', onUpdate='NO ACTION', columnNames=[singularStrength],
referenceColumnNames=[id]},
ForeignKey{referenceTable='Strengths', onDelete='NO ACTION', onUpdate='NO ACTION', columnNames=[pluralStrength],
referenceColumnNames=[id]}],
indices=[
Index{name='index_Strengths_singularStrength', unique=false, columns=[singularStrength]},
Index{name='index_Strengths_pluralStrength', unique=false, columns=[pluralStrength]}]}
Found:
TableInfo{
name='Strengths',
columns={
name=Column{name='name', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'},
singularStrength=Column{name='singularStrength', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0,
defaultValue='null'},
id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'},
pluralStrength=Column{name='pluralStrength', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0,
defaultValue='null'}},
foreignKeys=[
ForeignKey{referenceTable='strengths', onDelete='NO ACTION', onUpdate='NO ACTION', columnNames=[pluralStrength],
referenceColumnNames=[id]},
ForeignKey{referenceTable='strengths', onDelete='NO ACTION', onUpdate='NO ACTION', columnNames=[singularStrength],
referenceColumnNames=[id]}],
indices=[
Index{name='index_Strengths_singularStrength', unique=false, columns=[singularStrength]},
Index{name='index_Strengths_pluralStrength', unique=false, columns=[pluralStrength]}]}
显然,即使我想这样做,我也无法更改外键引用(因为它会检测到数据库被操纵)。我的问题是,是否有可能告诉Room,忽略外键表名的大小写。(因为它在create table语句中也会忽略它)有些人可能会认为问题是外键的顺序交换了,但是顺序并不重要。我已经在另一个表中检查过了,在这个表中,列是以交换顺序写的,它工作得很好。
所以我的问题是,如果有可能告诉Room,忽略外键中的大小写
我不相信你可以,因为这是房间建立比较(预期和发现)的固有方式。
你说,因为MySQL-Database对表名不区分大小写。SQLite也是如此,它是在运行时不接受差异的Room。
我建议这可能被认为是一个bug,我看到你似乎已经把它作为一个bug提出来了。
所以就像MikeT建议的那样,我向Google报告了这个bug。目前,这是一个简洁但简单的解决方案:只要让外键中引用的所有实体类全部小写即可。这样的:
@Entity(foreignKeys = [ForeignKey(entity = strengths::class, parentColumns = ["id"],
childColumns = ["singularStrength"]), ForeignKey(entity = strengths::class, parentColumns = ["id"],
childColumns = ["pluralStrength"])],
indices = [Index(value=["singularStrength"]), Index(value=["pluralStrength"])])
data class strengths(@PrimaryKey val id : Int, val singularStrength : Int, val pluralStrength : Int,
val name : String)
不太好,因为它违反了命名约定,但相当容易做到。