DBAPI/驱动管理器配方¶
这些配方展示了 ADBC Python 库的通用功能,这些功能不一定特定于任何一个驱动。
直接使用底层绑定¶
配方源文件: driver_manager_lowlevel.py
虽然推荐在通用情况下使用 DB-API 绑定,但底层绑定也是可用的。它们大多直接反映了 ADBC C API。在选择退出 DB-API 包装器的某些行为时,它们可能很有用。
27import pyarrow
28
29import adbc_driver_manager
30import adbc_driver_sqlite
驱动包仍然提供创建根 AdbcDatabase 对象的便利。
34db: adbc_driver_manager.AdbcDatabase = adbc_driver_sqlite.connect()
然后必须将数据库包装在 AdbcConnection 中。这在范围上类似于 DB-API 的 Connection 类。
38conn = adbc_driver_manager.AdbcConnection(db)
最后,我们可以将连接包装在 AdbcStatement 中,它大致对应于 DB-API 的 Cursor 类。
42stmt = adbc_driver_manager.AdbcStatement(conn)
现在我们可以直接设置查询。与常规 DB-API 绑定不同,这不会准备语句。(取决于驱动程序,这可能是一个区别,也可能不是,特别是在多次执行同一查询时。)
48stmt.set_sql_query("SELECT 1 AS THEANSWER")
当我们执行查询时,我们会得到一个 Arrow C Stream 接口 句柄(包装为 PyCapsule),我们需要使用像 PyArrow 这样的库来导入它。
58handle, rowcount = stmt.execute_query()
SQLite 驱动程序无法提前知道结果集的行数(其他驱动程序,如 PostgreSQL 驱动程序,可能知道)。
61assert rowcount == -1
我们可以使用 PyArrow API 来读取结果。
63reader = pyarrow.RecordBatchReader.from_stream(handle)
64assert reader.schema == pyarrow.schema([("THEANSWER", "int64")])
最后,我们必须清理所有对象。(它们也支持上下文管理器协议。)
67stmt.close()
68conn.close()
69db.close()
手动准备语句¶
配方源文件: driver_manager_prepare.py
DBAPI 绑定在执行前会准备所有语句,因为这是 DB-API 规范 的一部分
光标将保留对该操作的引用。如果再次传入相同的操作对象,则光标可以优化其行为。
但是,您可能希望自己准备语句,主要是因为这将为您提供参数的模式(如果服务器支持)。这可以通过 Cursor.adbc_prepare 完成。
我们将用 SQLite 驱动程序演示这一点,尽管其他驱动程序也支持此功能。
38import pyarrow
39
40import adbc_driver_sqlite.dbapi
41
42conn = adbc_driver_sqlite.dbapi.connect()
43
44with conn.cursor() as cur:
45 param_schema = cur.adbc_prepare("SELECT ? + 1")
46 assert param_schema == pyarrow.schema([("0", "null")])
请注意,此处参数的类型为 NULL,因为驱动程序不知道确切的类型。
如果我们现在用参数执行相同的查询,语句将不会被准备第二次。
54 cur.execute("SELECT ? + 1", parameters=(1,))
55 assert cur.fetchone() == (2,)
56
57 cur.execute("SELECT ? + 1", parameters=(41,))
58 assert cur.fetchone() == (42,)
59
60conn.close()