Sqlite3模块差异
这个 sqlite3 标准模块和APSW从根本不同的方向解决了从Python提供对SQLite的访问的问题。
APSW以任何对SQLite正常的方式提供访问。它毫不掩饰SQLite与其他数据库的不同之处。
Sqlite3尝试提供DBAPI (PEP 249 )兼容SQLite的包装器,并在这样做时需要使其具有与其他数据库相同的行为。因此,它确实隐藏了SQLite的一些细微差别。
备注
当您想要直接使用SQLite及其功能,或者使用您自己的代码来处理数据库独立性而不是DBAPI时,我建议使用APSW。使用 sqlite3
如果您的需求很简单,并且不想使用SQLite特定的功能,则可以使用DBAPI。
APSW在哪些方面做得更好
APSW与SQLITE3模块相比有以下增强/不同之处:
APSW通过SQLite保持最新状态。在SQLite中添加特性和更改功能时,APSW会对其进行跟踪。
APSW保持与Python的最新版本,包括开发中的版本以及仍然支持的旧版本。当前的APSW版本将最新的SQLite一直带到了Python3.8,一直到Python3.13。
APSW提供了SQLite的所有功能,包括 virtual tables , VFS , BLOB I/O , backups 和
file control
。您可以使用相同的
Connection
使用APSW跨线程,不需要任何额外级别的锁定。SQLITE 3 requires 那就是Connection
以及任何cursors
都在同一个线程中使用。您可以禁用它的检查,但除非您非常小心地使用自己的互斥锁,否则将会发生崩溃或死锁。APSW build instructions 向您展示如何在扩展中静态地包含SQLite,避免对系统SQLite的依赖。
Nothing 在你背后发生。默认情况下,sqlite3尝试通过为您解析您的SQL来管理事务(以符合DBAPI),但您可以将其关闭。这可能会导致使用SQLITE3时出现非常意外的行为。
在使用
Connection
作为一名context manager
APSW利用SQLite的能力 nested transactions 。Sqlite3有一个上下文管理器,但没有实现嵌套。您可以在命令的末尾使用分号,并且在APSW的执行字符串中可以有多个命令。对使用的命令类型没有限制。例如,这在APSW中可以正常工作,但在SQLITE3::中不允许这样做
import apsw con=apsw.Connection(":memory:") cur=con.cursor() for row in cur.execute("create table foo(x,y,z);insert into foo values (?,?,?);" "insert into foo values(?,?,?);select * from foo;drop table foo;" "create table bar(x,y);insert into bar values(?,?);" "insert into bar values(?,?);select * from bar;", (1,2,3,4,5,6,7,8,9,10)): print (row)
和您预期的输出::
(1, 2, 3) (4, 5, 6) (7, 8) (9, 10)
Cursor.executemany()
也适用于返回数据的语句,如SELECT,并且您可以有多个语句。SQLITE 3‘S executescript 方法不允许返回任何形式的数据(它会自动忽略任何返回的数据)。Sqlite3允许在回调中出现异常,这使得调试问题变得更加困难。这还防止您在回调中引发异常,以便在调用SQLite的代码中进行处理。Sqlite3确实可以让你打开 printing of tracebacks 但这是一个糟糕的替代品。
APSW做了正确的事情,如本例所示。APSW将Python错误转换为SQLite错误,因此SQLite知道发生了错误。
资料来源:
def badfunc(t): return 1/0 # sqlite3 import sqlite3 con = sqlite3.connect(":memory:") con.create_function("badfunc", 1, badfunc) cur = con.cursor() cur.execute("select badfunc(3)") # apsw import apsw con = apsw.Connection(":memory:") con.createscalarfunction("badfunc", badfunc, 1) cur = con.cursor() cur.execute("select badfunc(3)")
例外情况::
# sqlite3 Traceback (most recent call last): File "func.py", line 8, in ? cur.execute("select badfunc(3)") sqlite3.OperationalError: user-defined function raised exception # apsw Traceback (most recent call last): File "t.py", line 8, in ? cur.execute("select badfunc(3)") File "apsw.c", line 3660, in resetcursor File "apsw.c", line 1871, in user-defined-scalar-badfunc File "t.py", line 3, in badfunc return 1/0
APSW显著增强了可调试性。当上述异常发生时,除了打印输出的内容之外,还有更多的详细信息可用。看见 augmented stack traces
APSW有更好的 execution and row tracing 。 各种有趣和有用的功能 提供按列名访问行、类型转换、获取查询详细信息等功能。
APSW有一个 apswtrace 无需以任何方式修改代码即可跟踪执行并生成代码的实用程序脚本。它还输出摘要报告,便于查看您最耗时的查询、最受欢迎的查询等。
APSW有一个对应于每个SQLite错误代码的异常,并提供扩展的错误代码。Sqlite3将几个SQLite错误代码组合成相应的DBAPI异常。这是一个很好的例子,说明了这两个包装器在方法上的差异。
APSW测试套件更大,测试的功能更多。几乎所有的失败情况都经过了测试,包括内存不足、错误返回等。测试套件的代码覆盖率为99.6%。Sqlite3对于C代码的覆盖率为81%,尽管有几个地方可以提高覆盖率。我还没有测量过SQLITE3的S Python代码的代码覆盖率。这样做的结果是APSW更早地发现问题,并提供更好的诊断。例如,尝试从已注册的标量函数返回不受支持的类型。
在我的测试中,APSW比Sqlite3更快。试试 速测 基准。
哪种Sqlite3做得更好
Sqlite3是标准库的一部分,受到抽象数据库层的库的广泛支持