This is an automated email from the ASF dual-hosted git repository.
lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new 7076bee4f feat(python/adbc_driver_manager): add convenience methods
(#3539)
7076bee4f is described below
commit 7076bee4fc1f30a49668723bcccb7ea25bb19fc8
Author: David Li <[email protected]>
AuthorDate: Wed Oct 15 09:38:37 2025 +0900
feat(python/adbc_driver_manager): add convenience methods (#3539)
Closes #3263.
---
docs/source/python/quickstart.rst | 5 +++++
.../adbc_driver_manager/dbapi.py | 26 +++++++++++++++++++++-
python/adbc_driver_manager/tests/test_dbapi.py | 13 +++++++++++
3 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/docs/source/python/quickstart.rst
b/docs/source/python/quickstart.rst
index 9d6165f2d..0aef7c97b 100644
--- a/docs/source/python/quickstart.rst
+++ b/docs/source/python/quickstart.rst
@@ -73,6 +73,7 @@ row-oriented DBAPI interface:
:skipif: adbc_driver_sqlite is None
>>> cursor.execute("SELECT 1, 2.0, 'Hello, world!'")
+ <adbc_driver_manager.dbapi.Cursor ...>
>>> cursor.fetchone()
(1, 2.0, 'Hello, world!')
>>> cursor.fetchone()
@@ -83,6 +84,7 @@ We can also get the results as Arrow data via a non-standard
method:
:skipif: adbc_driver_sqlite is None
>>> cursor.execute("SELECT 1, 2.0, 'Hello, world!'")
+ <adbc_driver_manager.dbapi.Cursor ...>
>>> cursor.fetch_arrow_table()
pyarrow.Table
1: int64
@@ -102,6 +104,7 @@ We can bind parameters in our queries:
:skipif: adbc_driver_sqlite is None
>>> cursor.execute("SELECT ? + 1 AS the_answer", parameters=(41,))
+ <adbc_driver_manager.dbapi.Cursor ...>
>>> cursor.fetch_arrow_table()
pyarrow.Table
the_answer: int64
@@ -123,6 +126,7 @@ table of Arrow data into a new database table:
>>> cursor.adbc_ingest("sample", table)
2
>>> cursor.execute("SELECT COUNT(DISTINCT ints) FROM sample")
+ <adbc_driver_manager.dbapi.Cursor ...>
>>> cursor.fetchall()
[(2,)]
@@ -135,6 +139,7 @@ We can also append to an existing table:
>>> cursor.adbc_ingest("sample", table, mode="append")
2
>>> cursor.execute("SELECT COUNT(DISTINCT ints) FROM sample")
+ <adbc_driver_manager.dbapi.Cursor ...>
>>> cursor.fetchall()
[(3,)]
diff --git a/python/adbc_driver_manager/adbc_driver_manager/dbapi.py
b/python/adbc_driver_manager/adbc_driver_manager/dbapi.py
index 4c3641dca..cd0ecd72e 100644
--- a/python/adbc_driver_manager/adbc_driver_manager/dbapi.py
+++ b/python/adbc_driver_manager/adbc_driver_manager/dbapi.py
@@ -386,6 +386,22 @@ class Connection(_Closeable):
# API Extensions
# ------------------------------------------------------------
+ def execute(
+ self,
+ operation: Union[bytes, str],
+ parameters=None,
+ *,
+ adbc_stmt_kwargs: Optional[Dict[str, Any]] = None,
+ ) -> "Cursor":
+ """
+ Execute a query on a new cursor.
+
+ This is a convenience for creating a new cursor and executing a query.
+ """
+ return self.cursor(adbc_stmt_kwargs=adbc_stmt_kwargs).execute(
+ operation, parameters
+ )
+
def adbc_cancel(self) -> None:
"""
Cancel any ongoing operations on this connection.
@@ -723,7 +739,7 @@ class Cursor(_Closeable):
)
self._bind_by_name = False
- def execute(self, operation: Union[bytes, str], parameters=None) -> None:
+ def execute(self, operation: Union[bytes, str], parameters=None) -> "Self":
"""
Execute a query.
@@ -744,6 +760,11 @@ class Cursor(_Closeable):
Note that providing a list of tuples is not supported (this mode
of usage is deprecated in DBAPI-2.0; use executemany() instead).
+
+ Returns
+ -------
+ Self
+ This cursor (to enable chaining).
"""
self._clear()
self._prepare_execute(operation, parameters)
@@ -752,6 +773,7 @@ class Cursor(_Closeable):
self._stmt.execute_query, (), {}, self._stmt.cancel
)
self._results = _RowIterator(self._stmt, handle)
+ return self
def executemany(self, operation: Union[bytes, str], seq_of_parameters) ->
None:
"""
@@ -775,6 +797,8 @@ class Cursor(_Closeable):
-----
Allowing ``None`` for parameters is outside of the DB-API
specification.
+
+ This does not return ``self`` as there is no result set.
"""
self._clear()
if operation != self._last_query:
diff --git a/python/adbc_driver_manager/tests/test_dbapi.py
b/python/adbc_driver_manager/tests/test_dbapi.py
index 72ae18f9e..b68cca210 100644
--- a/python/adbc_driver_manager/tests/test_dbapi.py
+++ b/python/adbc_driver_manager/tests/test_dbapi.py
@@ -530,3 +530,16 @@ def test_driver_path():
):
with dbapi.connect(driver=pathlib.Path("/tmp/thisdriverdoesnotexist")):
pass
+
+
[email protected]
+def test_dbapi_extensions(sqlite):
+ with sqlite.execute("SELECT ?", (1,)) as cur:
+ assert cur.fetchone() == (1,)
+ assert cur.fetchone() is None
+
+ assert cur.execute("SELECT 2").fetchall() == [(2,)]
+
+ with sqlite.cursor() as cur:
+ assert cur.execute("SELECT 1").fetchall() == [(1,)]
+ assert cur.execute("SELECT 42").fetchall() == [(42,)]