Skip to content

Mature execute_query API #911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
See also https://github.com/neo4j/neo4j-python-driver/wiki for more details.

## NEXT RELEASE
- ...
- Renamed experimental `neo4j.RoutingControl.READERS` to `READ` and `WRITERS` to `WRITE`.
- Renamed experimental `driver.query_bookmark_manager` to `execute_query_bookmark_manager`.


## Version 5.7
Expand Down
16 changes: 8 additions & 8 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Closing a driver will immediately shut down all connections in the pool.
verify_connectivity, get_server_info, verify_authentication,
supports_session_auth, supports_multi_db

.. method:: execute_query(query, parameters_=None,routing_=neo4j.RoutingControl.WRITERS, database_=None, impersonated_user_=None, bookmark_manager_=self.query_bookmark_manager, result_transformer_=Result.to_eager_result, **kwargs)
.. method:: execute_query(query, parameters_=None,routing_=neo4j.RoutingControl.WRITE, database_=None, impersonated_user_=None, bookmark_manager_=self.query_bookmark_manager, result_transformer_=Result.to_eager_result, **kwargs)

Execute a query in a transaction function and return all results.

Expand Down Expand Up @@ -194,9 +194,9 @@ Closing a driver will immediately shut down all connections in the pool.
bookmark_manager=bookmark_manager_,
auth=auth_,
) as session:
if routing_ == RoutingControl.WRITERS:
if routing_ == RoutingControl.WRITE:
return session.execute_write(work)
elif routing_ == RoutingControl.READERS:
elif routing_ == RoutingControl.READ:
return session.execute_read(work)

Usage example::
Expand All @@ -211,7 +211,7 @@ Closing a driver will immediately shut down all connections in the pool.
records, summary, keys = driver.execute_query(
"MATCH (p:Person {age: $age}) RETURN p.name",
{"age": 42},
routing_=neo4j.RoutingControl.READERS, # or just "r"
routing_=neo4j.RoutingControl.READ, # or just "r"
database_="neo4j",
)
assert keys == ["p.name"] # not needed, just for illustration
Expand All @@ -232,7 +232,7 @@ Closing a driver will immediately shut down all connections in the pool.
"SET p.nickname = 'My dear' "
"RETURN count(*)",
# optional routing parameter, as write is default
# routing_=neo4j.RoutingControl.WRITERS, # or just "w",
# routing_=neo4j.RoutingControl.WRITE, # or just "w",
database_="neo4j",
result_transformer_=neo4j.Result.single,
age=15,
Expand Down Expand Up @@ -380,7 +380,8 @@ Closing a driver will immediately shut down all connections in the pool.
.. versionadded:: 5.5

.. versionchanged:: 5.8
Added the ``auth_`` parameter.
* Added the ``auth_`` parameter.
* Stabilized from experimental.


.. _driver-configuration-ref:
Expand Down Expand Up @@ -1022,8 +1023,7 @@ See :class:`.BookmarkManager` for more information.

.. versionadded:: 5.0

**This is experimental** (see :ref:`filter-warnings-ref`).
It might be changed or removed any time even without prior notice.
.. versionchanged:: 5.8 stabilized from experimental


.. _session-auth-ref:
Expand Down
23 changes: 8 additions & 15 deletions docs/source/async_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Closing a driver will immediately shut down all connections in the pool.
verify_connectivity, get_server_info, verify_authentication,
supports_session_auth, supports_multi_db

.. method:: execute_query(query, parameters_=None, routing_=neo4j.RoutingControl.WRITERS, database_=None, impersonated_user_=None, bookmark_manager_=self.query_bookmark_manager, result_transformer_=AsyncResult.to_eager_result, **kwargs)
.. method:: execute_query(query, parameters_=None, routing_=neo4j.RoutingControl.WRITE, database_=None, impersonated_user_=None, bookmark_manager_=self.query_bookmark_manager, result_transformer_=AsyncResult.to_eager_result, **kwargs)
:async:

Execute a query in a transaction function and return all results.
Expand Down Expand Up @@ -184,9 +184,9 @@ Closing a driver will immediately shut down all connections in the pool.
bookmark_manager=bookmark_manager_,
auth=auth_,
) as session:
if routing_ == RoutingControl.WRITERS:
if routing_ == RoutingControl.WRITE:
return await session.execute_write(work)
elif routing_ == RoutingControl.READERS:
elif routing_ == RoutingControl.READ:
return await session.execute_read(work)

Usage example::
Expand All @@ -201,7 +201,7 @@ Closing a driver will immediately shut down all connections in the pool.
records, summary, keys = await driver.execute_query(
"MATCH (p:Person {age: $age}) RETURN p.name",
{"age": 42},
routing_=neo4j.RoutingControl.READERS, # or just "r"
routing_=neo4j.RoutingControl.READ, # or just "r"
database_="neo4j",
)
assert keys == ["p.name"] # not needed, just for illustration
Expand All @@ -222,7 +222,7 @@ Closing a driver will immediately shut down all connections in the pool.
"SET p.nickname = 'My dear' "
"RETURN count(*)",
# optional routing parameter, as write is default
# routing_=neo4j.RoutingControl.WRITERS, # or just "w",
# routing_=neo4j.RoutingControl.WRITE, # or just "w",
database_="neo4j",
result_transformer_=neo4j.AsyncResult.single,
age=15,
Expand Down Expand Up @@ -360,17 +360,11 @@ Closing a driver will immediately shut down all connections in the pool.
:returns: the result of the ``result_transformer``
:rtype: T

**This is experimental** (see :ref:`filter-warnings-ref`).
It might be changed or removed any time even without prior notice.

We are looking for feedback on this feature. Please let us know what
you think about it here:
https://github.com/neo4j/neo4j-python-driver/discussions/896

.. versionadded:: 5.5

.. versionchanged:: 5.8
Added the ``auth_`` parameter.
* Added the ``auth_`` parameter.
* Stabilized from experimental.


.. _async-driver-configuration-ref:
Expand Down Expand Up @@ -659,8 +653,7 @@ See :class:`BookmarkManager` for more information.
:Type: :data:`None`, :class:`BookmarkManager`, or :class:`AsyncBookmarkManager`
:Default: :data:`None`

**This is experimental** (see :ref:`filter-warnings-ref`).
It might be changed or removed any time even without prior notice.
.. versionchanged:: 5.8 stabilized from experimental



Expand Down
15 changes: 8 additions & 7 deletions src/neo4j/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,21 +208,22 @@ class RoutingControl(str, Enum):
Inherits from :class:`str` and :class:`Enum`. Every driver API accepting a
:class:`.RoutingControl` value will also accept a string

>>> RoutingControl.READERS == "r"
>>> RoutingControl.READ == "r"
True
>>> RoutingControl.WRITERS == "w"
>>> RoutingControl.WRITE == "w"
True

**This is experimental.**
It might be changed or removed any time even without prior notice.

.. seealso::
:attr:`.AsyncDriver.execute_query`, :attr:`.Driver.execute_query`

.. versionadded:: 5.5

.. versionchanged:: 5.8
* renamed ``READERS`` to ``READ`` and ``WRITERS`` to ``WRITE``
* stabilized from experimental
"""
READERS = "r"
WRITERS = "w"
READ = "r"
WRITE = "w"


if t.TYPE_CHECKING:
Expand Down
1 change: 1 addition & 0 deletions src/neo4j/_async/auth_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# work around for https://github.com/sphinx-doc/sphinx/pull/10880
# make sure TAuth is resolved in the docs, else they're pretty useless


import time
import typing as t
from logging import getLogger
Expand Down
73 changes: 21 additions & 52 deletions src/neo4j/_async/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@
)
from .._meta import (
deprecation_warn,
experimental,
experimental_warn,
ExperimentalWarning,
preview,
preview_warn,
PreviewWarning,
Expand Down Expand Up @@ -293,10 +291,6 @@ def driver(
routing_context=routing_context, **config)

@classmethod
@experimental(
"The bookmark manager feature is experimental. "
"It might be changed or removed any time even without prior notice."
)
def bookmark_manager(
cls,
initial_bookmarks: t.Union[None, Bookmarks, t.Iterable[str]] = None,
Expand Down Expand Up @@ -357,9 +351,6 @@ def bookmark_manager(

:returns: A default implementation of :class:`AsyncBookmarkManager`.

**This is experimental** (see :ref:`filter-warnings-ref`).
It might be changed or removed any time even without prior notice.

.. versionadded:: 5.0

.. versionchanged:: 5.3
Expand All @@ -373,6 +364,8 @@ def bookmark_manager(
an argument.
* ``bookmarks_consumer`` no longer receives the database name as
an argument.

.. versionchanged:: 5.8 stabilized from experimental
"""
return AsyncNeo4jBookmarkManager(
initial_bookmarks=initial_bookmarks,
Expand Down Expand Up @@ -480,12 +473,7 @@ def __init__(self, pool, default_workspace_config):
assert default_workspace_config is not None
self._pool = pool
self._default_workspace_config = default_workspace_config
with warnings.catch_warnings():
warnings.filterwarnings("ignore",
message=r".*\bbookmark manager\b.*",
category=ExperimentalWarning)
self._query_bookmark_manager = \
AsyncGraphDatabase.bookmark_manager()
self._query_bookmark_manager = AsyncGraphDatabase.bookmark_manager()

async def __aenter__(self) -> AsyncDriver:
return self
Expand Down Expand Up @@ -579,7 +567,7 @@ async def execute_query(
self,
query_: str,
parameters_: t.Optional[t.Dict[str, t.Any]] = None,
routing_: T_RoutingControl = RoutingControl.WRITERS,
routing_: T_RoutingControl = RoutingControl.WRITE,
database_: t.Optional[str] = None,
impersonated_user_: t.Optional[str] = None,
bookmark_manager_: t.Union[
Expand All @@ -598,7 +586,7 @@ async def execute_query(
self,
query_: str,
parameters_: t.Optional[t.Dict[str, t.Any]] = None,
routing_: T_RoutingControl = RoutingControl.WRITERS,
routing_: T_RoutingControl = RoutingControl.WRITE,
database_: t.Optional[str] = None,
impersonated_user_: t.Optional[str] = None,
bookmark_manager_: t.Union[
Expand All @@ -612,15 +600,11 @@ async def execute_query(
) -> _T:
...

@experimental(
"Driver.execute_query is experimental. "
"It might be changed or removed any time even without prior notice."
)
async def execute_query(
self,
query_: str,
parameters_: t.Optional[t.Dict[str, t.Any]] = None,
routing_: T_RoutingControl = RoutingControl.WRITERS,
routing_: T_RoutingControl = RoutingControl.WRITE,
database_: t.Optional[str] = None,
impersonated_user_: t.Optional[str] = None,
bookmark_manager_: t.Union[
Expand Down Expand Up @@ -661,9 +645,9 @@ async def work(tx):
bookmark_manager=bookmark_manager_,
auth=auth_,
) as session:
if routing_ == RoutingControl.WRITERS:
if routing_ == RoutingControl.WRITE:
return await session.execute_write(work)
elif routing_ == RoutingControl.READERS:
elif routing_ == RoutingControl.READ:
return await session.execute_read(work)

Usage example::
Expand All @@ -678,7 +662,7 @@ async def example(driver: neo4j.AsyncDriver) -> List[str]:
records, summary, keys = await driver.execute_query(
"MATCH (p:Person {age: $age}) RETURN p.name",
{"age": 42},
routing_=neo4j.RoutingControl.READERS, # or just "r"
routing_=neo4j.RoutingControl.READ, # or just "r"
database_="neo4j",
)
assert keys == ["p.name"] # not needed, just for illustration
Expand All @@ -699,7 +683,7 @@ async def example(driver: neo4j.AsyncDriver) -> int:
"SET p.nickname = 'My dear' "
"RETURN count(*)",
# optional routing parameter, as write is default
# routing_=neo4j.RoutingControl.WRITERS, # or just "w",
# routing_=neo4j.RoutingControl.WRITE, # or just "w",
database_="neo4j",
result_transformer_=neo4j.AsyncResult.single,
age=15,
Expand Down Expand Up @@ -837,17 +821,11 @@ async def example(driver: neo4j.AsyncDriver) -> neo4j.Record::
:returns: the result of the ``result_transformer``
:rtype: T

**This is experimental** (see :ref:`filter-warnings-ref`).
It might be changed or removed any time even without prior notice.

We are looking for feedback on this feature. Please let us know what
you think about it here:
https://github.com/neo4j/neo4j-python-driver/discussions/896

.. versionadded:: 5.5

.. versionchanged:: 5.8
Added the ``auth_`` parameter.
* Added the ``auth_`` parameter.
* Stabilized from experimental.
"""
invalid_kwargs = [k for k in kwargs if
k[-2:-1] != "_" and k[-1:] == "_"]
Expand All @@ -866,9 +844,6 @@ async def example(driver: neo4j.AsyncDriver) -> neo4j.Record::
assert bookmark_manager_ is not _default

with warnings.catch_warnings():
warnings.filterwarnings("ignore",
message=r".*\bbookmark_manager\b.*",
category=ExperimentalWarning)
warnings.filterwarnings("ignore",
message=r"^User switching\b.*",
category=PreviewWarning)
Expand All @@ -877,9 +852,9 @@ async def example(driver: neo4j.AsyncDriver) -> neo4j.Record::
bookmark_manager=bookmark_manager_,
auth=auth_)
async with session:
if routing_ == RoutingControl.WRITERS:
if routing_ == RoutingControl.WRITE:
executor = session.execute_write
elif routing_ == RoutingControl.READERS:
elif routing_ == RoutingControl.READ:
executor = session.execute_read
else:
raise ValueError("Invalid routing control value: %r"
Expand All @@ -889,11 +864,7 @@ async def example(driver: neo4j.AsyncDriver) -> neo4j.Record::
)

@property
@experimental(
"Driver.query_bookmark_manager is experimental. "
"It might be changed or removed any time even without prior notice."
)
def query_bookmark_manager(self) -> AsyncBookmarkManager:
def execute_query_bookmark_manager(self) -> AsyncBookmarkManager:
"""The driver's default query bookmark manager.

This is the default :class:`AsyncBookmarkManager` used by
Expand All @@ -912,10 +883,12 @@ async def example(driver: neo4j.AsyncDriver) -> None:
# (i.e., can read what was written by <QUERY 2>)
await driver.execute_query("<QUERY 3>")

**This is experimental** (see :ref:`filter-warnings-ref`).
It might be changed or removed any time even without prior notice.

.. versionadded:: 5.5

.. versionchanged:: 5.8
* Renamed from ``query_bookmark_manager`` to
``execute_query_bookmark_manager``.
* Stabilized from experimental.
"""
return self._query_bookmark_manager

Expand Down Expand Up @@ -1212,11 +1185,7 @@ async def _work(
) -> _T:
res = await tx.run(query, parameters)
if transformer is AsyncResult.to_eager_result:
with warnings.catch_warnings():
warnings.filterwarnings("ignore",
message=r".*\bto_eager_result\b.*",
category=ExperimentalWarning)
return await transformer(res)
return await transformer(res)
return await transformer(res)


Expand Down
Loading