为什么Core Data SQLite存储不能从OS X 10.8到10.4向后兼容?

问题描述:

如果我的应用程序在Mountain Lion上创建了一个新的Core Data存储(SQLite 3.7.12),当尝试在Tiger(SQLite 3.1.3)上打开该文件时,该应用程序收到NSPersistentStoreInvalidTypeError错误。在Tiger Mac上运行sqlite3命令行工具在打开数据库时不会产生任何错误,但“.dump”命令显示SQLite认为它是空的。为什么Core Data SQLite存储不能从OS X 10.8到10.4向后兼容?

但是,如果数据库是在Tiger上创建的,则可以在Mountain Lion上编辑,然后在Tiger上再次编辑,而不会出现任何问题。

Mountain Lion是否发生了一些变化,使新创建的持久性商店不再向后兼容?还是有一个我可以启用的设置,以便它们是?据我所知,我没有使用3.1.3中没有的更新的SQLite特性,例如预写式日志记录。另外,这在Lion上创建的数据库不是问题。

更新:SQLite change history显示版本3.7.10中存在文件格式更改。您应该能够设置PRAGMA legacy_file_format=ON

当这个标志是,在一个文件 格式,可读可写的SQLite由去 回3.0.0的所有版本都创造了新的SQLite数据库。

这适用于我直接使用sqlite3。但是,当我通过NSSQLitePragmasOption选项将其设置为NSPersistentStoreCoordinator时,它似乎被忽略:在Tiger上的sqlite3再次将数据库视为空。

首先,一个术语问题。根据Wikipedia,我相信你在这里讨论的问题是forward compatibility:“向前兼容的目的在于设计能够优雅地接受用于其自身更高版本的输入。”在这种情况下,随OS X 10.4发布的sqlite3(3.1.3)版本是否能够处理由OS X 10.8中较新版本的sqlite3(3.7.12)创建的磁盘数据格式?

根据sqlite3 documentation,sqlite3并没有承诺磁盘格式将完全向前兼容,只能在极限内向后兼容,也就是说,新版本可以读取由旧版本生成的数据库。使用sqlite外壳的一个简单的数据库创建示例很容易演示,虽然10.4版本创建的数据库可以被10.8版本读取,但反过来并不正确。恰巧我有一个10.4机器(PPC),恰好拥有sqlite3的一个先进的最新版本与苹果公司提供的系统版本一起:

$ /macports/bin/sqlite3 -version 
3.7.13 2012-06-11 02:05:22 f5b5a13f7394dc143aa136f1d4faba6839eaa6dc 
$ /macports/bin/sqlite3 test.db <<EOF 
>  BEGIN TRANSACTION; 
>  CREATE TABLE t1 (t1key INTEGER 
>     PRIMARY KEY,data TEXT,num double,timeEnter DATE); 
>  INSERT INTO "t1" VALUES(1, 'This is sample data', 3, NULL); 
>  INSERT INTO "t1" VALUES(2, 'More sample data', 6, NULL); 
>  INSERT INTO "t1" VALUES(3, 'And a little more', 9, NULL); 
>  COMMIT; 
> EOF 
$ /macports/bin/sqlite3 test.db "select * from t1 limit 2"; 
1|This is sample data|3.0| 
2|More sample data|6.0| 
$ /usr/bin/sqlite3 test.db "select * from t1 limit 2"; 
SQL error: unsupported file format 
$ /usr/bin/sqlite3 -version 
3.1.3 

如果创建的数据库上的同样的事情发生10.8,然后转移到10.4。当使用10.7版本的sqlite3(3.7.7)运行相同的测试时,10.4版本能够读取数据库文件。我认为这些格式长期以来一直保持向前兼容,这真是一件好事。看来运气现在已经用完了。除非Apple在某些地方保证CoreData SQL数据库在这些OS X版本的范围内向前兼容,否则您可能需要在应用程序中处理这种兼容性,例如,通过跨数据库转储和重新创建版本。

+0

感谢您的回答。我认为你对术语是正确的。据我所知,苹果公司并没有作出保证,但它通常的工作方式是苹果明确告诉你什么时候会发生什么事情。如果NSPropertyListSerialization或NSKeyedArchiver突然更改格式,将会出现混乱。我已经更新了有关SQLite格式兼容性的信息,我相信他们承诺。 – 2012-08-09 15:32:04