我正在尝试以编程方式备份房间数据库。
为此,我只需复制包含整个数据库的.sqlite
文件
但是,在复制之前,由于房间启用了预写日志,我们必须关闭数据库,以便将-shm
文件和-wal
文件合并到单个.sqlite
文件中。As pointed out here
我对RoomDatabase
对象运行.close()
:
备份一切正常,但稍后,当我尝试执行INSERT
查询时,我收到以下错误:
android.database.sqlite.SQLiteException: no such table: room_table_modification_log (code 1)
关闭房间db后如何正确重新打开?
Ps:RoomDatabase
对象上的.isOpen()
在INSERT
之前返回true
房型:1.1.1-rc1
7条答案
按热度按时间but5z9lq1#
这并没有回答最初的问题
关闭房间db后如何正确地重新打开它?
但是,将所有内容移动到原始数据库文件是您想要做的,这样您就不必首先关闭数据库。相反,您可以使用
wal_checkpoint
杂注强制检查点。针对数据库查询以下语句。我们在这里使用原始查询,因为Room还不支持
pragma
(它将触发UNKNOWN query type
错误)。在您的DAO中包含以下查询:然后,当您调用检查点方法时,使用以下查询:
这一链接可能会为
wal_checkpoint
的功能提供一些线索。ncecgwcz2#
为了更确切地回答你的问题,这是我如何在我的一个应用程序中备份房间数据库的。
1.检查对外部存储器的读/写权限。如果您写入您的应用程序文件目录,则可以忽略此步骤。
1.关闭你的
RoomDatabase
。在我的例子中,AppDatabase
指的是一个单例,它包含最初用于构建房间数据库的逻辑。AppDatabase.getInstance(this).getDatabase()
获取从RoomDatabase
扩展的单例及其当前数据库类的当前示例。这实际上称为RoomDatabase.close()
。1.定义源文件和目标文件,具体取决于备份或还原。我包括SHM和WAL文件,即使它们是临时文件。
1.使用您选择的方法复制文件。在本例中,
FileUtils
指的是commons-io
。代码
mo49yndu3#
作为替代方案,您可以始终创建Room数据库,同时强制其不使用预写日志记录:
2lpgd9684#
为了更确切地回答你的问题,这是我如何在我的一个应用程序中备份房间数据库的。
1-检查对外部存储器的读/写权限。2-关闭您的房间数据库。在我的例子中,AppDatabase指的是一个单例,它包含最初用于构建房间数据库的逻辑。GetInstance(this@MainActivity)获取从RoomDatabase扩展的单例及其当前数据库类的当前示例。3-然后实质上调用dbInstance.Close()。
您必须将保存的文件包含在
以便在出现任何错误时进行排序,并避免应用程序崩溃。
要从CurrentTimeMillis中获取日期,请使用以下函数
重启数据库代码*将文件对象传递给Uri.from文件
或返回结果的开始活动的结果
RestoreDatabase函数
**现在需要将备份中的文件复制到真实的数据库文件中使用复制文件
idv4meu85#
需要做的第一件事是创建具有适当日记模式的数据库。
之后,需要执行以下检查点查询,以确保应用所有挂起的事务。
为此,需要向数据库DAO接口添加以下方法
然后需要使用以下SQL查询调用该方法
一旦检查点方法成功,就可以最终保存数据库备份文件。
最后,可以使用以下代码检索数据库备份文件
然后需要将该文件复制到备份文件位置。
要恢复文件,需要做的唯一一件事是用备份文件覆盖数据库文件(这可以使用上面的片段检索)。
你可以在我的博客上读到更详细的内容
https://androidexplained.github.io/android/room/2020/10/03/room-backup-restore.html
a11xaf1n6#
首先,必须关闭数据库才能应用
"dbName.db-wal"
文件中的更改。然后,您可以复制包含所有表和上次数据更改的数据库
fdbelqdn7#
上面已经回答过了。无需关闭/重新打开数据库。
我在我的安卓应用程序中使用MVVM模式来备份数据库文件,以便将其上传到Google Drive。我只想总结一下对我有效的解决方案:
在DAO文件中提到以下代码:
在您的存储库文件中提到以下代码:
在您的ViewModel中提到以下内容:
现在,您可以在从活动文件执行备份之前调用此方法