是否可以使用 sqldelight 从本地资源加载预填充的数据库

Jaf*_*hid 6 kotlin sqldelight kotlin-multiplatform

我有一个相对较大的数据库,可能需要 1 到 2 分钟才能初始化,是否可以在使用 sqldelight(kotlin 多平台)时加载预先填充的数据库,而不是在应用程序启动时初始化数据库?

Den*_*cev 6

抱歉,我还不能添加任何评论,这会更合适......


虽然没有直接回答你的问题,但 1 到 2 分钟对于 sqlite 来说确实非常长。你在干什么?我首先要确保您正确使用交易。1-2 分钟的插入数据(可能)会产生一个巨大的数据库文件。

另外,由于我必须使用预先填充的数据库,所以我的问题与大尺寸的 .sq 文件(每个表的 INSERT 文本超过 30 MB)相关,并且 SqlDeLight 默默地中断了生成,而不显示错误消息。


在初始化 sqldelight 之前,您需要将 db 文件放在 Android 上的 asset 中和 iOS 上的捆绑包中,并将它们复制到各自的文件夹中。

必须从 android 和 ios 上的资源加载数据库感觉工作量很大,这意味着共享项目不会是初始化数据的唯一位置。

Kotlin MultiPlatform 库Moko-resources解决了共享模块中数据库的单一来源问题。它适用于 KMM,与适用于 Android 和 iOS 的方式相同。

不幸的是,使用此功能几乎没有在库的示例中出现。我在期望的类DatabaseDriverFactory中添加了第二个方法(getDriver)来打开准备好的数据库,并在平台上实现了它。例如,对于 androidMain:

actual class DatabaseDriverFactory(private val context: Context) {
    actual fun createDriver(schema: SqlDriver.Schema, fileName: String): SqlDriver {
        return AndroidSqliteDriver(schema, context, fileName)
    }

    actual fun getDriver(schema: SqlDriver.Schema, fileName: String): SqlDriver {
        val database: File = context.getDatabasePath(fileName)

        if (!database.exists()) {
            val inputStream = context.resources.openRawResource(MR.files.dbfile.rawResId)
            val outputStream = FileOutputStream(database.absolutePath)

            inputStream.use { input: InputStream ->
                outputStream.use { output: FileOutputStream ->
                    input.copyTo(output)
                }
            }
        }

        return AndroidSqliteDriver(schema, context, fileName)
    }
}
Run Code Online (Sandbox Code Playgroud)

MR.files.fullDb 是库生成的类中的 FileResource,它与位于 commonMain 模块的 resources/MR/files 目录中的文件的名称相关联。它的属性rawResId代表平台端资源ID。


Kev*_*gan 1

是的,但这可能很棘手。不仅仅是“多平台”。在尝试初始化 sqldelight 之前,您需要将 db 复制到 db 文件夹。这可能意味着应用程序启动时主线程上的 I/O。

现在没有标准方法可以做到这一点。在初始化 sqldelight 之前,您需要将 db 文件放在 Android 上的 asset 中和 iOS 上的捆绑包中,并将它们复制到各自的文件夹中。显然,您需要首先检查数据库是否存在,或者通过某种方式知道这是您的第一个应用程序运行。

如果您计划发布将包含较新数据库的更新,则除了检查数据库是否存在之外,您还需要管理版本。

虽然没有直接回答你的问题,但 1 到 2 分钟对于 sqlite 来说确实非常长。你在干什么?我首先要确保您正确使用交易。1-2 分钟的插入数据(可能)会产生一个巨大的数据库文件。