Android SQLDelight (七) 从 Room 迁移的改造点

更新日期: 2023-05-27 阅读次数: 876 字数: 473 分类: Android

继续将原有的 Compose 项目重写为 XML View,本来不想折腾,心想要不直接沿用原来的 Room 代码,但是看了 DAO 和 Repository 这种风格的代码,还是忍不了。

既然没有退路了,就得保证对历史数据的兼容。

数据库名称

注意,用 SQLDelight 指定数据库名称时,不要加 .db 后缀。否则跟之前 Room 生成的文件名不一致。

-  val driver: SqlDriver = AndroidSqliteDriver(Database.Schema, context, "item_database.db")
+  val driver: SqlDriver = AndroidSqliteDriver(Database.Schema, context, "item_database")

Version Error

SQLDelight 不像 Room 可以通过注解参数指定数据库版本号。所以在手机上测试升级时,会报一个运行时错误,直接导致 app 崩溃:

android.database.sqlite.SQLiteException: Can't downgrade database from version 5 to 1

之前的 Room db version 为 5,看来 SQLDelight 默认为 1。

@Database(entities = [Item::class], version = 5, exportSchema = false)
@TypeConverters(Converters::class)
abstract class ItemDatabase : RoomDatabase() {
    abstract fun itemDao(): ItemDao

	// ...
}

如何设置 SQLDelight 数据库版本号

下面是一个可行的方案:

在与 data 的同级目录,创建一个 migrations 目录,然后创建 4 个 sqm migration 文件。 可以参考 Room 之前的 migration 操作生成每个文件的内容, 但我的情况特殊,第五版是我的第一个 release 版本,所以直接创建了 4 个空的 sqm 文件。

app/src/main/sqldelight/com/sunzhongwei/someapp/
├── data
│   └── Item.sq
└── migrations
    ├── 1.sqm
    ├── 2.sqm
    ├── 3.sqm
    └── 4.sqm

SQLDelight 的数据库版本号,由最大的 sqm 文件名决定,即,N.sqm 代表当前版本号为 N + 1。

例如:

有 4 个 .sqm 文件,代表当前 database 的版本号是 5。

打印版本号

println("database version is: " + Database.Schema.version)
val driver: SqlDriver = AndroidSqliteDriver(Database.Schema, context, "item_database")

database version is: 5

注意:

不能直接修改 Database.Schema.version,因为 version 是 val 类型的,不可修改。

探索更多关于 SQLDelight

📖 Android Room 替代品 SQLDelight 中文入门教程

参考

  • https://medium.com/xorum-io/migration-from-room-to-sqldelight-28d6f4aaf31e
  • https://cashapp.github.io/sqldelight/2.0.0-alpha05/android_sqlite/migrations/

tags: sqldelight android room

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式