备份 .sqlite(核心数据) [英] Backing up .sqlite (Core Data)

查看:25
本文介绍了备份 .sqlite(核心数据)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于核心数据的应用程序,它使用 Dropbox 来备份和恢复数据.我备份的方式非常简单.我将 .sqlite 文件复制到用户的保管箱中.

I have a core data based application that uses Dropbox to backup and restore data. The way I backup is pretty straight forward. I copy the .sqlite file on the user's dropbox.

现在我的备份和恢复功能运行良好.问题在于 .sqlite 文件本身..sqlite 文件似乎不完整.

Now my backup and restore functionality are working fine. The issue is with the .sqlite file itself. It appears that the .sqlite file is incomplete.

我在应用程序中输入了大约 125 个条目并进行了备份.备份出现在我的保管箱中,但是当我使用 .sqlite 资源管理器工具查看内容时,我只能看到第 117 个条目的记录.

I entered about 125 entries in my application and took a backup. The backup appeared in my dropbox but when I use a .sqlite explorer tool to see the contents, I only see records upto 117th entry.

我尝试更新第一个条目,然后再次观察 .sqlite 文件,但没有再次更改.

I tried updating the first entry and then again observing .sqlite file but no changes again.

更奇怪的是,该应用似乎记录了所有更改.当我添加新条目或更新现有条目并重新启动应用程序时,新添加的数据似乎仍然存在.但是这个新添加的数据并没有出现在我的.sqlite文件中.

What's even more strange is that the app appears to have recorded all changes. When I add a new entry or update an existing one and restart the app, the newly added data seems to persist. But this newly added data does not appear in my .sqlite file.

我正在使用此代码进行备份:

I am backing up using this code:

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSString *filePath = [[[appDelegate applicationDocumentsDirectory] path] stringByAppendingPathComponent:@"MyApp.sqlite"];


if (account) {
    if ([filesystem isShutDown]) {
        filesystem = [[DBFilesystem alloc] initWithAccount:account];
        [DBFilesystem setSharedFilesystem:filesystem];
    }

    DBPath *newPath = [[DBPath root] childPath:[NSString stringWithFormat:@"Backup - %@.sqlite", [NSDate date]]];
    DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil];
    [file writeContentsOfFile:filePath shouldSteal:NO error:nil];
    [filesystem shutDown];

}

我还从模拟器的文件夹中复制了 .sqlite 文件,并尝试在 .sqlite 浏览器中查看它.它仍然表现出相同的行为.为什么一定要发生这种情况?

I also copied the .sqlite file from the Simulator's folder and tried seeing it in the .sqlite browser. It still exhibits the same behaviour. Any reason why this must be happening?

推荐答案

从 iOS 7/OS X 10.9 开始,Core Data 默认使用Write-Ahead Logging"(WAL)底层 SQLite 存储文件的日志模式.这在

Starting with iOS 7 / OS X 10.9, Core Data uses "Write-Ahead Logging" (WAL) as default journaling mode for the underlying SQLite store file. This is explained in

技术问答 QA1809:Core Data SQLite 的新默认日志模式在 iOS 7 和 OS X Mavericks 中存储

在 WAL 模式下,Core Data 保持主存储文件不变,并且将交易附加到同一位置的 -wal 文件.之后保存Core Data上下文,不删除-wal文件,数据在该文件中也不会合并到存储文件中.因此,只需制作存储文件的副本可能会导致数据丢失和不一致.

With the WAL mode, Core Data keeps the main store file untouched and appends transactions to a -wal file in the same location. After the Core Data context is saved, the -wal file is not deleted, and the data in that file is not merged to the store file either. Therefore, simply making copies of the store file will likely cause data loss and inconsistency.

这应该可以解释为什么单独的 .sqlite 文件是不完整的.作为解决方案,您可以(也在该技术说明中进行了解释):

That should explain why your .sqlite file alone is incomplete. As as solution you can (also explained in that Technical Note):

  • 通过设置

  • Disable WAL-mode (and use the "old" rollback journaling mode) for the SQLite store by setting the

@{NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}};

添加持久存储时的选项,或

option when adding the persistent store, or

使用

- (NSPersistentStore *)migratePersistentStore:(NSPersistentStore *)store toURL:(NSURL *)URL options:(NSDictionary *)options withType:(NSString *)storeType error:(NSError **)error

制作核心数据存储备份副本的方法.

method to make a backup copy of the Core Data store.

这篇关于备份 .sqlite(核心数据)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆