房间给出错误:预打包的数据库的FTS表具有无效的架构

我正在开发字典应用程序,该应用程序使用FTS表提供搜索。 这些定义来自预先打包的数据库,该数据库具有以下架构:(.schema从Linux上的sqlite3程序输出)

sqlite> .open words.db
sqlite> .schema
CREATE TABLE entries
    (id INTEGER PRIMARY KEY NOT NULL,word TEXT NOT NULL COLLATE NOCASE,wordtype TEXT NOT NULL COLLATE NOCASE,definition TEXT NOT NULL COLLATE NOCASE);
CREATE INDEX words_index ON entries(id,word);
CREATE VIRTUAL TABLE entriesFts USING FTS4(content='entries',word)
/* entriesFts(word) */;
CREATE TABLE IF NOT EXISTS 'entriesFts_segments'(blockid INTEGER PRIMARY KEY,block BLOB);
CREATE TABLE IF NOT EXISTS 'entriesFts_segdir'(level INTEGER,idx INTEGER,start_block INTEGER,leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level,idx));
CREATE TABLE IF NOT EXISTS 'entriesFts_docsize'(docid INTEGER PRIMARY KEY,size BLOB);
CREATE TABLE IF NOT EXISTS 'entriesFts_stat'(id INTEGER PRIMARY KEY,value BLOB);

我的实体定义如下:

@Entity(tableName="entries",indices = [Index(name = "words_index",value = ["id","word"])])
data class Word (
    @PrimaryKey val id :Int,@ColumnInfo val word :String,@ColumnInfo(name = "wordtype") val wordType :String,@ColumnInfo val definition :String
)

/* Used when displaying list of words */
@Fts4(contentEntity = Word::class)
@Entity(tableName = "entriesFts")
data class WordMinimal (
    @PrimaryKey @ColumnInfo(name = "rowid") val id :Int,@ColumnInfo val word :String
)

在我看来,这些模式完全匹配,但是Room的看法不同:/
它在logcat中引发此错误:

java.lang.IllegalStateException: pre-packaged database has an invalid schema: entriesFts(rawderm.dictionary.en.db.WordMinimal).
     Expected:
    FtsTableInfo{name='entriesFts',columns=[word],options=[content=`entries`]}
     Found:
    FtsTableInfo{name='entriesFts',options=[content='entries']}
dfasdfewrt 回答:房间给出错误:预打包的数据库的FTS表具有无效的架构

房间非常类似于用于封闭名称的字符,并且基本上只接受带有重音符号的`(ASCII码96)用于封闭列名称。

对列进行编码的最安全方法是使用重音符号,因为这是Room所做的。说获得准确模式的最简便方法是让Room代表您生成模式代码。

您可以通过创建实体以及数据库类(即扩展Room Database的类),然后进行编译(Ctrl + F9),然后在生成的代码中查找作为数据库类的代码,来执行此操作名称后面加上_Impl。在该类中,将有一个 createAllTables 方法。其中包含Room 期望所期望的表的SQL,该表根据实体而定。

这样,Room会方便地生成:-

    _db.execSQL("CREATE TABLE IF NOT EXISTS `entries` (`id` INTEGER NOT NULL,`word` TEXT NOT NULL,`wordtype` TEXT NOT NULL,`definition` TEXT NOT NULL,PRIMARY KEY(`id`))");
    _db.execSQL("CREATE INDEX IF NOT EXISTS `words_index` ON `entries` (`id`,`word`)");
    _db.execSQL("CREATE VIRTUAL TABLE IF NOT EXISTS `entriesFts` USING FTS4(`word` TEXT NOT NULL,content=`entries`)");
    _db.execSQL("CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_entriesFts_BEFORE_UPDATE BEFORE UPDATE ON `entries` BEGIN DELETE FROM `entriesFts` WHERE `docid`=OLD.`rowid`; END");
    _db.execSQL("CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_entriesFts_BEFORE_DELETE BEFORE DELETE ON `entries` BEGIN DELETE FROM `entriesFts` WHERE `docid`=OLD.`rowid`; END");
    _db.execSQL("CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_entriesFts_AFTER_UPDATE AFTER UPDATE ON `entries` BEGIN INSERT INTO `entriesFts`(`docid`,`word`) VALUES (NEW.`rowid`,NEW.`word`); END");
    _db.execSQL("CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_entriesFts_AFTER_INSERT AFTER INSERT ON `entries` BEGIN INSERT INTO `entriesFts`(`docid`,NEW.`word`); END");
  • 请注意,它如何另外创建触发器来维护FTS。而且不需要将它们指定为或在实体中指定(即您可以将SQLite组件作为实体不存在,并且Room不会检测到不匹配)。
本文链接:https://www.f2er.com/3133946.html

大家都在问