如何检查Python中是否存在SQLite3数据库?

max*_*xim 18 python sqlite python-2.7

我试图在Python 2.7.3中创建一个函数来打开SQLite数据库.

这是我目前的代码:

import sqlite3 as lite
import sys

db = r'someDb.sqlite'

def opendb(db):
    try:
        conn = lite.connect(db)
    except sqlite3.Error:
        print "Error open db.\n"
        return False
    cur = conn.cursor()
    return [conn, cur]
Run Code Online (Sandbox Code Playgroud)

我已经尝试了上面的代码,并且我观察到该sqlite3库打开了声明的数据库(如果存在),或者如果此数据库不存在则创建新数据库.

有没有办法检查数据库是否存在sqlite3方法,还是我必须使用文件操作os.path.isfile(path)

Mar*_*ers 25

在Python 2中,您必须使用以下方法显式测试存在os.path.isfile:

if os.path.isfile(db):
Run Code Online (Sandbox Code Playgroud)

无法强制该sqlite3.connect功能不为您创建文件.


对于那些使用Python 3.4或更高版本的用户,可以使用较新的URI路径功能在打开数据库时设置不同的模式.sqlite3.connect()默认情况下,该函数将打开数据库rwc,即读取,写入和创建模式,因此连接到不存在的数据库将导致它被创建.

使用URI,您可以指定其他模式; 如果你把它设置为rw,所以读写模式,一个异常尝试连接到一个不存在的数据库时提出.uri=True在连接和传入file:URI 时设置标志时可以设置不同的模式,并mode=rw在路径中添加查询参数:

from urllib.request import pathname2url

try:
    dburi = 'file:{}?mode=rw'.format(pathname2url(db))
    conn = lite.connect(dburi, uri=True)
except sqlite3.OperationalError:
    # handle missing database case
Run Code Online (Sandbox Code Playgroud)

有关接受哪些参数的更多详细信息,请参阅SQLite URI已识别查询参数文档.


小智 19

os.path.isfile()只是告诉你文件是否存在,而不是它是否存在并且是一个SQLite3数据库!了解http://www.sqlite.org/fileformat.html,您可以这样做:

def isSQLite3(filename):
    from os.path import isfile, getsize

    if not isfile(filename):
        return False
    if getsize(filename) < 100: # SQLite database file header is 100 bytes
        return False

    with open(filename, 'rb') as fd:
        header = fd.read(100)

    return header[:16] == 'SQLite format 3\x00'
Run Code Online (Sandbox Code Playgroud)

然后使用它像:

for file in files:
    if isSQLite3(file):
        print "'%s' is a SQLite3 database file" % file
    else:
        print "'%s' is not a SQLite3 database file" % file
Run Code Online (Sandbox Code Playgroud)

  • 对于Python 3,请确保与字节进行比较:`Header [0:16] == b'SQLite format 3\000'`(注意格式字符串的前导`b` (7认同)

Jur*_*tić 7

是的,有一种方法可以用 Python 3.4+ 来做你想做的事。

使用该sqlite3.connect()函数进行连接,但向其传递 URI 而不是文件路径,并添加mode=rw到其查询字符串中。

这是一个完整的工作代码示例:

import sqlite3
con = sqlite3.connect('file:aaa.db?mode=rw', uri=True)
Run Code Online (Sandbox Code Playgroud)

这将从当前文件夹中命名的文件打开现有数据库aaa.db,但如果该文件无法打开或不存在,则会引发错误:

Traceback (most recent call last):
  File "aaa.py", line 2, in <module>
    con = sqlite3.connect('file:aaa.db?mode=rw', uri=True)
sqlite3.OperationalError: unable to open database file
Run Code Online (Sandbox Code Playgroud)

Python sqlite.connect() 文档指出:

如果 uri 为 true,则数据库将被解释为 URI。这允许您指定选项。例如,要以只读模式打开数据库,您可以使用:

db = sqlite3.connect('文件:路径/到/数据库?mode=ro', uri=True)

有关此功能的更多信息(包括可识别选项的列表)可以在SQLite URI 文档中找到。

以下是从http://www.sqlite.org/c3ref/open.html收集的所有相关 URI 选项信息的摘录:

mode:模式参数可以设置为“ro”、“rw”、“rwc”或“memory”。尝试将其设置为任何其他值都是错误的。如果指定“ro”,则数据库将以只读访问方式打开,就像在 sqlite3_open_v2() 的第三个参数中设置了 SQLITE_OPEN_READONLY 标志一样。如果模式选项设置为“rw”,则数据库将打开以进行读写(但不是创建)访问,就像已设置 SQLITE_OPEN_READWRITE(但不是 SQLITE_OPEN_CREATE)一样。值“rwc”相当于设置 SQLITE_OPEN_READWRITE 和 SQLITE_OPEN_CREATE。如果模式选项设置为“内存”,则使用从不从磁盘读取或写入的纯内存数据库。如果为模式参数指定的值比第三个参数中传递给 sqlite3_open_v2() 的标志所指定的限制更少,则这是错误的。

sqlite3_open_v2 ()接口的工作方式与 sqlite3_open() 类似,只是它接受两个附加参数以对新数据库连接进行额外控制。sqlite3_open_v2() 的 flags 参数可以采用以下三个值之一,可以选择与 SQLITE_OPEN_NOMUTEX、SQLITE_OPEN_FULLMUTEX、SQLITE_OPEN_SHAREDCACHE、SQLITE_OPEN_PRIVATECACHE 和/或 SQLITE_OPEN_URI 标志组合:

SQLITE_OPEN_READONLY 数据库以只读模式打开。如果数据库尚不存在,则返回错误。

SQLITE_OPEN_READWRITE 打开数据库以进行读写(如果可能),或者仅在文件受操作系统写保护时进行读取。无论哪种情况,数据库都必须已经存在,否则会返回错误。

SQLITE_OPEN_READWRITE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE 打开数据库进行读写,如果数据库尚不存在则创建该数据库。这是 sqlite3_open() 和 sqlite3_open16() 始终使用的行为。

为了方便起见,这里还有一个 Python 3.4+ 函数,用于将常规路径转换为 ​​sqlite.connect() 可用的 URI:

import pathlib
import urllib.parse

def _path_to_uri(path):
    path = pathlib.Path(path)
    if path.is_absolute():
        return path.as_uri()
    return 'file:' + urllib.parse.quote(path.as_posix(), safe=':/')
Run Code Online (Sandbox Code Playgroud)