Skip to content

Rename Session.x_transaction to Session.execute_x #784

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 2 commits into from
Aug 30, 2022
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@
Server-side keep-alives communicated through configuration hints together with
the config option `connection_acquisition_timeout` are sufficient to avoid the
driver getting stuck.
- Deprecate `Session.read_transaction` and `Session.write_transaction` in favor
of `Session.execute_read` and `Session.execute_write` respectively.


## Version 4.4
Expand Down
4 changes: 4 additions & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,12 @@ Session

.. automethod:: read_transaction

.. automethod:: execute_read

.. automethod:: write_transaction

.. automethod:: execute_write


Query
=====
Expand Down
4 changes: 4 additions & 0 deletions docs/source/async_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,12 @@ AsyncSession

.. automethod:: read_transaction

.. automethod:: execute_read

.. automethod:: write_transaction

.. automethod:: execute_write



.. _async-session-configuration-ref:
Expand Down
4 changes: 2 additions & 2 deletions neo4j/_async/work/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ async def create_node_tx(tx, name):
return value, summary

async with driver.session() as session:
node_id, summary = await session.write_transaction(
node_id, summary = await session.execute_write(
create_node_tx, "example"
)

Expand All @@ -376,7 +376,7 @@ async def get_two_tx(tx):
return values, summary

async with driver.session() as session:
values, summary = await session.read_transaction(get_two_tx)
values, summary = await session.execute_read(get_two_tx)

:returns: The :class:`neo4j.ResultSummary` for this result

Expand Down
125 changes: 125 additions & 0 deletions neo4j/_async/work/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,75 @@ async def _run_transaction(
else:
raise ServiceUnavailable("Transaction failed")

async def execute_read(
self,
transaction_function: t.Callable[
te.Concatenate[AsyncManagedTransaction, _P], t.Awaitable[_R]
],
*args: _P.args, **kwargs: _P.kwargs
) -> _R:
"""Execute a unit of work in a managed read transaction.

.. note::
This does not necessarily imply access control, see the session
configuration option :ref:`default-access-mode-ref`.

This transaction will automatically be committed when the function
returns, unless an exception is thrown during query execution or by
the user code. Note, that this function performs retries and that the
supplied `transaction_function` might get invoked more than once.
Therefore, it needs to be idempotent (i.e., have the same effect,
regardless if called once or many times).

Example::

async def do_cypher_tx(tx, cypher):
result = await tx.run(cypher)
values = [record.values() async for record in result]
return values

async with driver.session() as session:
values = await session.execute_read(do_cypher_tx, "RETURN 1 AS x")

Example::

async def get_two_tx(tx):
result = await tx.run("UNWIND [1,2,3,4] AS x RETURN x")
values = []
async for record in result:
if len(values) >= 2:
break
values.append(record.values())
# or shorter: values = [record.values()
# for record in await result.fetch(2)]

# discard the remaining records if there are any
summary = await result.consume()
# use the summary for logging etc.
return values

async with driver.session() as session:
values = await session.execute_read(get_two_tx)

:param transaction_function: a function that takes a transaction as an
argument and does work with the transaction.
`transaction_function(tx, *args, **kwargs)` where `tx` is a
:class:`.AsyncManagedTransaction`.
:param args: additional arguments for the `transaction_function`
:param kwargs: key word arguments for the `transaction_function`

:raises SessionError: if the session has been closed.

:return: a result as returned by the given unit of work

.. versionadded:: 5.0
"""
return await self._run_transaction(
READ_ACCESS, transaction_function, *args, **kwargs
)

# TODO 6.0: Remove this method
@deprecated("read_transaction has been renamed to execute_read")
async def read_transaction(
self,
transaction_function: t.Callable[
Expand Down Expand Up @@ -590,11 +659,64 @@ async def get_two_tx(tx):
:raises SessionError: if the session has been closed.

:return: a result as returned by the given unit of work

.. deprecated:: 5.0
Method was renamed to :meth:`.execute_read`.
"""
return await self._run_transaction(
READ_ACCESS, transaction_function, *args, **kwargs
)

async def execute_write(
self,
transaction_function: t.Callable[
te.Concatenate[AsyncManagedTransaction, _P], t.Awaitable[_R]
],
*args: _P.args, **kwargs: _P.kwargs
) -> _R:
"""Execute a unit of work in a managed write transaction.

.. note::
This does not necessarily imply access control, see the session
configuration option :ref:`default-access-mode-ref`.

This transaction will automatically be committed when the function
returns unless, an exception is thrown during query execution or by
the user code. Note, that this function performs retries and that the
supplied `transaction_function` might get invoked more than once.
Therefore, it needs to be idempotent (i.e., have the same effect,
regardless if called once or many times).

Example::

async def create_node_tx(tx, name):
query = "CREATE (n:NodeExample { name: $name }) RETURN id(n) AS node_id"
result = await tx.run(query, name=name)
record = await result.single()
return record["node_id"]

async with driver.session() as session:
node_id = await session.execute_write(create_node_tx, "example")

:param transaction_function: a function that takes a transaction as an
argument and does work with the transaction.
`transaction_function(tx, *args, **kwargs)` where `tx` is a
:class:`.AsyncManagedTransaction`.
:param args: additional arguments for the `transaction_function`
:param kwargs: key word arguments for the `transaction_function`

:raises SessionError: if the session has been closed.

:return: a result as returned by the given unit of work

.. versionadded:: 5.0
"""
return await self._run_transaction(
WRITE_ACCESS, transaction_function, *args, **kwargs
)

# TODO 6.0: Remove this method
@deprecated("write_transaction has been renamed to execute_write")
async def write_transaction(
self,
transaction_function: t.Callable[
Expand Down Expand Up @@ -636,6 +758,9 @@ async def create_node_tx(tx, name):
:raises SessionError: if the session has been closed.

:return: a result as returned by the given unit of work

.. deprecated:: 5.0
Method was renamed to :meth:`.execute_write`.
"""
return await self._run_transaction(
WRITE_ACCESS, transaction_function, *args, **kwargs
Expand Down
4 changes: 2 additions & 2 deletions neo4j/_sync/work/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ def create_node_tx(tx, name):
return value, summary

with driver.session() as session:
node_id, summary = session.write_transaction(
node_id, summary = session.execute_write(
create_node_tx, "example"
)

Expand All @@ -376,7 +376,7 @@ def get_two_tx(tx):
return values, summary

with driver.session() as session:
values, summary = session.read_transaction(get_two_tx)
values, summary = session.execute_read(get_two_tx)

:returns: The :class:`neo4j.ResultSummary` for this result

Expand Down
125 changes: 125 additions & 0 deletions neo4j/_sync/work/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,75 @@ def _run_transaction(
else:
raise ServiceUnavailable("Transaction failed")

def execute_read(
self,
transaction_function: t.Callable[
te.Concatenate[ManagedTransaction, _P], t.Union[_R]
],
*args: _P.args, **kwargs: _P.kwargs
) -> _R:
"""Execute a unit of work in a managed read transaction.

.. note::
This does not necessarily imply access control, see the session
configuration option :ref:`default-access-mode-ref`.

This transaction will automatically be committed when the function
returns, unless an exception is thrown during query execution or by
the user code. Note, that this function performs retries and that the
supplied `transaction_function` might get invoked more than once.
Therefore, it needs to be idempotent (i.e., have the same effect,
regardless if called once or many times).

Example::

def do_cypher_tx(tx, cypher):
result = tx.run(cypher)
values = [record.values() for record in result]
return values

with driver.session() as session:
values = session.execute_read(do_cypher_tx, "RETURN 1 AS x")

Example::

def get_two_tx(tx):
result = tx.run("UNWIND [1,2,3,4] AS x RETURN x")
values = []
for record in result:
if len(values) >= 2:
break
values.append(record.values())
# or shorter: values = [record.values()
# for record in result.fetch(2)]

# discard the remaining records if there are any
summary = result.consume()
# use the summary for logging etc.
return values

with driver.session() as session:
values = session.execute_read(get_two_tx)

:param transaction_function: a function that takes a transaction as an
argument and does work with the transaction.
`transaction_function(tx, *args, **kwargs)` where `tx` is a
:class:`.ManagedTransaction`.
:param args: additional arguments for the `transaction_function`
:param kwargs: key word arguments for the `transaction_function`

:raises SessionError: if the session has been closed.

:return: a result as returned by the given unit of work

.. versionadded:: 5.0
"""
return self._run_transaction(
READ_ACCESS, transaction_function, *args, **kwargs
)

# TODO 6.0: Remove this method
@deprecated("read_transaction has been renamed to execute_read")
def read_transaction(
self,
transaction_function: t.Callable[
Expand Down Expand Up @@ -590,11 +659,64 @@ def get_two_tx(tx):
:raises SessionError: if the session has been closed.

:return: a result as returned by the given unit of work

.. deprecated:: 5.0
Method was renamed to :meth:`.execute_read`.
"""
return self._run_transaction(
READ_ACCESS, transaction_function, *args, **kwargs
)

def execute_write(
self,
transaction_function: t.Callable[
te.Concatenate[ManagedTransaction, _P], t.Union[_R]
],
*args: _P.args, **kwargs: _P.kwargs
) -> _R:
"""Execute a unit of work in a managed write transaction.

.. note::
This does not necessarily imply access control, see the session
configuration option :ref:`default-access-mode-ref`.

This transaction will automatically be committed when the function
returns unless, an exception is thrown during query execution or by
the user code. Note, that this function performs retries and that the
supplied `transaction_function` might get invoked more than once.
Therefore, it needs to be idempotent (i.e., have the same effect,
regardless if called once or many times).

Example::

def create_node_tx(tx, name):
query = "CREATE (n:NodeExample { name: $name }) RETURN id(n) AS node_id"
result = tx.run(query, name=name)
record = result.single()
return record["node_id"]

with driver.session() as session:
node_id = session.execute_write(create_node_tx, "example")

:param transaction_function: a function that takes a transaction as an
argument and does work with the transaction.
`transaction_function(tx, *args, **kwargs)` where `tx` is a
:class:`.ManagedTransaction`.
:param args: additional arguments for the `transaction_function`
:param kwargs: key word arguments for the `transaction_function`

:raises SessionError: if the session has been closed.

:return: a result as returned by the given unit of work

.. versionadded:: 5.0
"""
return self._run_transaction(
WRITE_ACCESS, transaction_function, *args, **kwargs
)

# TODO 6.0: Remove this method
@deprecated("write_transaction has been renamed to execute_write")
def write_transaction(
self,
transaction_function: t.Callable[
Expand Down Expand Up @@ -636,6 +758,9 @@ def create_node_tx(tx, name):
:raises SessionError: if the session has been closed.

:return: a result as returned by the given unit of work

.. deprecated:: 5.0
Method was renamed to :meth:`.execute_write`.
"""
return self._run_transaction(
WRITE_ACCESS, transaction_function, *args, **kwargs
Expand Down
4 changes: 2 additions & 2 deletions testkitbackend/_async/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,9 @@ async def func(tx):
raise FrontendError("Client said no")

if is_read:
await session.read_transaction(func)
await session.execute_read(func)
else:
await session.write_transaction(func)
await session.execute_write(func)
await backend.send_response("RetryableDone", {})


Expand Down
4 changes: 2 additions & 2 deletions testkitbackend/_sync/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,9 @@ def func(tx):
raise FrontendError("Client said no")

if is_read:
session.read_transaction(func)
session.execute_read(func)
else:
session.write_transaction(func)
session.execute_write(func)
backend.send_response("RetryableDone", {})


Expand Down
Loading