-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: add recipe for
adbc_prepare
and low-level bindings (#2097)
Relates to #2040.
- Loading branch information
Showing
3 changed files
with
141 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one | ||
# or more contributor license agreements. See the NOTICE file | ||
# distributed with this work for additional information | ||
# regarding copyright ownership. The ASF licenses this file | ||
# to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance | ||
# with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, | ||
# software distributed under the License is distributed on an | ||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations | ||
# under the License. | ||
|
||
# RECIPE STARTS HERE | ||
#: While the DB-API_ bindings are recommended for general use, the low-level | ||
#: bindings are also available. These mostly mirror the ADBC C API directly. | ||
#: They can be useful to opt out of some behaviors of the DB-API wrapper. | ||
#: | ||
#: .. _DB-API: https://peps.python.org/pep-0249/ | ||
|
||
import pyarrow | ||
|
||
import adbc_driver_manager | ||
import adbc_driver_sqlite | ||
|
||
#: The driver packages do still have conveniences to create the root | ||
#: :class:`AdbcDatabase <adbc_driver_manager.AdbcDatabase>` object. | ||
db: adbc_driver_manager.AdbcDatabase = adbc_driver_sqlite.connect() | ||
#: The database must then be wrapped in a :class:`AdbcConnection | ||
#: <adbc_driver_manager.AdbcConnection>`. This is similar in scope to the | ||
#: DB-API :class:`Connection <adbc_driver_manager.dbapi.Connection>` class. | ||
conn = adbc_driver_manager.AdbcConnection(db) | ||
#: Finally, we can wrap the connection in a :class:`AdbcStatement | ||
#: <adbc_driver_manager.AdbcStatement>`, which corresponds roughly to the | ||
#: DB-API :class:`Cursor <adbc_driver_manager.dbapi.Cursor>` class. | ||
stmt = adbc_driver_manager.AdbcStatement(conn) | ||
|
||
#: Now we can directly set the query. Unlike the regular DB-API bindings, this | ||
#: will not prepare the statement. (Depending on the driver, this may or may | ||
#: not make a difference, especially if executing the same query multiple | ||
#: times.) | ||
stmt.set_sql_query("SELECT 1 AS THEANSWER") | ||
|
||
#: When we execute the query, we get an `Arrow C Stream Interface`_ handle | ||
#: (wrapped as a PyCapsule_) that we need to import using a library like | ||
#: PyArrow_. | ||
#: | ||
#: .. _Arrow C Stream Interface: | ||
#: https://arrow.apache.org/docs/format/CStreamInterface.html | ||
#: .. _PyArrow: https://pypi.org/project/pyarrow/ | ||
#: .. _PyCapsule: https://docs.python.org/3/c-api/capsule.html | ||
handle, rowcount = stmt.execute_query() | ||
#: The SQLite driver does not know the row count of the result set up front | ||
#: (other drivers, like the PostgreSQL driver, may know). | ||
assert rowcount == -1 | ||
#: We can use the PyArrow APIs to read the result. | ||
reader = pyarrow.RecordBatchReader._import_from_c_capsule(handle.__arrow_c_stream__()) | ||
assert reader.schema == pyarrow.schema([("THEANSWER", "int64")]) | ||
#: Finally, we have to clean up all the objects. (They also support the | ||
#: context manager protocol.) | ||
stmt.close() | ||
conn.close() | ||
db.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one | ||
# or more contributor license agreements. See the NOTICE file | ||
# distributed with this work for additional information | ||
# regarding copyright ownership. The ASF licenses this file | ||
# to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance | ||
# with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, | ||
# software distributed under the License is distributed on an | ||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations | ||
# under the License. | ||
|
||
# RECIPE STARTS HERE | ||
#: The DBAPI bindings prepare all statements before execution, because of this | ||
#: part of the `DB-API specification`_: | ||
#: | ||
#: A reference to the operation will be retained by the cursor. If the same | ||
#: operation object is passed in again, then the cursor can optimize its | ||
#: behavior. | ||
#: | ||
#: However, you may want to prepare the statement yourself, mostly because this | ||
#: will give you the schema of the parameters (if supported by the server). | ||
#: This can be done with :meth:`Cursor.adbc_prepare | ||
#: <adbc_driver_manager.dbapi.Cursor.adbc_prepare>`. | ||
#: | ||
#: We'll demo this with the SQLite driver, though other drivers also support | ||
#: this. | ||
#: | ||
#: .. _DB-API specification: https://peps.python.org/pep-0249/#id19 | ||
|
||
import pyarrow | ||
|
||
import adbc_driver_sqlite.dbapi | ||
|
||
conn = adbc_driver_sqlite.dbapi.connect() | ||
|
||
with conn.cursor() as cur: | ||
param_schema = cur.adbc_prepare("SELECT ? + 1") | ||
assert param_schema == pyarrow.schema([("0", "null")]) | ||
|
||
#: Note that the type of the parameter here is NULL, because the driver | ||
#: does not know the exact type. | ||
|
||
#: If we now execute the same query with the parameter, the statement will | ||
#: not be prepared a second time. | ||
|
||
cur.execute("SELECT ? + 1", parameters=(1,)) | ||
assert cur.fetchone() == (2,) | ||
|
||
cur.execute("SELECT ? + 1", parameters=(41,)) | ||
assert cur.fetchone() == (42,) | ||
|
||
conn.close() |