检查数据库文件是否有效及程序的预期?
在用Python(2.6版本)连接SQLite数据库时,有哪些方法可以确保程序打开的是一个有效的数据库文件(这里的有效是指“符合程序的预期”)呢?
我想确保在进行一些打开检查后,可以(合理地)确认程序打开的是一个能正常工作的数据库文件——理想情况下,如果文件是新的或空的,就可以CREATE
所有内容;如果文件是其他用途的数据库,或者文件损坏,就应该停止操作并发出警告。
我在想,关键可能是比较打开的文件的结构和程序中预期的结构?
如果是这样的话,应该怎么做呢?
如果不是,还有什么其他方法可以采取?
2 个回答
3
SQLite有一个叫做pragma user_version的功能,可以在数据库里存储任何你想要的数字。通常情况下,你可以用它来跟踪你自己数据库的版本,比如说你应用的第一个版本是1,当你在三次更新后改变了数据库结构,就可以把它设置为2,这样你的代码就能知道数据库结构已经升级了。
不过,你也可以从任何你想要的数字开始,比如说从3656672354开始,然后在这个基础上增加,用来进行内部版本跟踪。其他数据库出现这个范围内的数字几乎是不可能的。
3
在我需要类似功能的解决方案中,我通常会在代码所在的同一目录下保留一个 .sql
文件,这个文件里包含了数据库的构建指令,内容类似于下面的例子:
# setup
PRAGMA foreign_keys=ON;
PRAGMA journal_mode=TRUNCATE;
PRAGMA locking_mode=EXCLUSIVE;
PRAGMA synchronous=NORMAL;
# Locations
CREATE TABLE IF NOT EXISTS Locations (
locID INTEGER PRIMARY KEY,
locPath TEXT NOT NULL
);
# blah-blah
CREATE UNIQUE INDEX IF NOT EXISTS fldPath_idx
ON Folders(fldPath);
# and so on
我会确保所有的 SQL 语句在行末以分号结束,分号是行中最后一个非空白字符,因为我有一些代码像下面这个方法,会确保每次我的应用程序启动时都能运行这些指令:
def db_schema(self):
cur= self._db.cursor()
with io.open(self.SQLPATH, "r") as fp:
sql_statement= ""
for line in fp:
line= line.rstrip()
if line.startswith('#'): continue
sql_statement+= line
if line.endswith(";"):
try:
cur.execute(sql_statement)
except sql.OperationalError:
print("Failed:\n%s" % sql_statement)
sql_statement= ""
# file is done
cur.close()
注意使用了 CREATE TABLE IF NOT EXISTS
和 CREATE INDEX IF NOT EXISTS
这样的语句。