检查数据库文件是否有效及程序的预期?

5 投票
2 回答
1079 浏览
提问于 2025-04-16 19:18

在用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 EXISTSCREATE INDEX IF NOT EXISTS 这样的语句。

撰写回答