【问题标题】:Is it possible to make Android Room tables case insensitive?是否可以使 Android Room 表不区分大小写?
【发布时间】:2021-08-03 14:21:12
【问题描述】:

我在本地计算机上创建了一个数据库,以将其预填充到 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,忽略外键表名中的大小写。 (因为它在创建表语句中也忽略了它) 有些人可能会认为问题在于外键的切换顺序,但是顺序并不重要。已经用另一个表检查过,其中的列是按切换顺序写入的,它工作得非常好。

【问题讨论】:

    标签: mysql sqlite schema android-room case-insensitive


    【解决方案1】:

    所以我的问题是,如果有可能告诉 Room,忽略外键中的大小写。

    我不相信你可以,因为这是空间构建比较的固有方式(预期和发现)。

    您说由于 MySQL 数据库对表名不区分大小写。 SQLite 也是如此,它是 Room 在运行时不接受差异。

    我建议这可能被视为一个错误,我看到您似乎已将其作为bug 提出。

    【讨论】:

    • 是的,我把它作为一个错误提出来,因为我也认为它是错误的行为。希望他们能解决。现在,我只需要将所有引用的实体都设为小写即可。
    【解决方案2】:

    按照 MikeT 的建议,我将其作为错误报告给了 Google。目前他们是一个简洁但简单的解决方法: 只需将外键中引用的所有实体类都设为小写即可。 像这样:

    @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)
    

    不太好,因为它违反了命名约定,但相当容易做到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-16
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-24
      相关资源
      最近更新 更多