query.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. # Copyright (c) "Neo4j"
  2. # Neo4j Sweden AB [https://neo4j.com]
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # https://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. from __future__ import annotations
  16. import typing as t
  17. if t.TYPE_CHECKING:
  18. import typing_extensions as te
  19. _T = t.TypeVar("_T")
  20. class Query:
  21. """
  22. A query with attached extra data.
  23. This wrapper class for queries is used to attach extra data to queries
  24. passed to :meth:`.Session.run`/:meth:`.AsyncSession.run` and
  25. :meth:`.Driver.execute_query`/:meth:`.AsyncDriver.execute_query`,
  26. fulfilling a similar role as :func:`.unit_of_work` for transactions
  27. functions.
  28. :param text: The query text.
  29. :type text: typing.LiteralString
  30. :param metadata:
  31. a dictionary with metadata.
  32. Specified metadata will be attached to the executing transaction
  33. and visible in the output of ``SHOW TRANSACTIONS YIELD *``
  34. It will also get logged to the ``query.log``.
  35. This functionality makes it easier to tag transactions and is
  36. equivalent to the ``dbms.setTXMetaData`` procedure, see
  37. https://neo4j.com/docs/cypher-manual/current/clauses/transaction-clauses/#query-listing-transactions
  38. and https://neo4j.com/docs/operations-manual/current/reference/procedures/
  39. for reference.
  40. :type metadata: typing.Dict[str, typing.Any] | None
  41. :param timeout:
  42. the transaction timeout in seconds.
  43. Transactions that execute longer than the configured timeout will
  44. be terminated by the database.
  45. This functionality allows user code to limit query/transaction
  46. execution time.
  47. The specified timeout overrides the default timeout configured in
  48. the database using the ``db.transaction.timeout`` setting
  49. (``dbms.transaction.timeout`` before Neo4j 5.0).
  50. Values higher than ``db.transaction.timeout`` will be ignored and
  51. will fall back to the default for server versions between 4.2 and
  52. 5.2 (inclusive).
  53. The value should not represent a negative duration.
  54. A ``0`` duration will make the transaction execute indefinitely.
  55. :data:`None` will use the default timeout configured on the server.
  56. :type timeout: float | None
  57. """
  58. def __init__(
  59. self,
  60. text: te.LiteralString,
  61. metadata: dict[str, t.Any] | None = None,
  62. timeout: float | None = None,
  63. ) -> None:
  64. self.text = text
  65. self.metadata = metadata
  66. self.timeout = timeout
  67. def __str__(self) -> te.LiteralString:
  68. # we know that if Query is constructed with a LiteralString,
  69. # str(self.text) will be a LiteralString as well. The conversion isn't
  70. # necessary if the user adheres to the type hints. However, it was
  71. # here before, and we don't want to break backwards compatibility.
  72. text: te.LiteralString = str(self.text) # type: ignore[assignment]
  73. return text
  74. def unit_of_work(
  75. metadata: dict[str, t.Any] | None = None,
  76. timeout: float | None = None,
  77. ) -> t.Callable[[_T], _T]:
  78. """
  79. Configure a transaction function.
  80. This function is a decorator for transaction functions that allows extra
  81. control over how the transaction is carried out.
  82. For example, a timeout may be applied::
  83. from neo4j import unit_of_work
  84. @unit_of_work(timeout=100)
  85. def count_people_tx(tx):
  86. result = tx.run("MATCH (a:Person) RETURN count(a) AS persons")
  87. record = result.single()
  88. return record["persons"]
  89. :param metadata:
  90. a dictionary with metadata.
  91. Specified metadata will be attached to the executing transaction
  92. and visible in the output of ``SHOW TRANSACTIONS YIELD *``
  93. It will also get logged to the ``query.log``.
  94. This functionality makes it easier to tag transactions and is
  95. equivalent to the ``dbms.setTXMetaData`` procedure, see
  96. https://neo4j.com/docs/cypher-manual/current/clauses/transaction-clauses/#query-listing-transactions
  97. and https://neo4j.com/docs/operations-manual/current/reference/procedures/
  98. for reference.
  99. :type metadata: typing.Dict[str, typing.Any] | None
  100. :param timeout:
  101. the transaction timeout in seconds.
  102. Transactions that execute longer than the configured timeout will
  103. be terminated by the database.
  104. This functionality allows user code to limit query/transaction
  105. execution time.
  106. The specified timeout overrides the default timeout configured in
  107. the database using the ``db.transaction.timeout`` setting
  108. (``dbms.transaction.timeout`` before Neo4j 5.0).
  109. Values higher than ``db.transaction.timeout`` will be ignored and
  110. will fall back to the default for server versions between 4.2 and
  111. 5.2 (inclusive).
  112. The value should not represent a negative duration.
  113. A ``0`` duration will make the transaction execute indefinitely.
  114. :data:`None` will use the default timeout configured on the server.
  115. :type timeout: float | None
  116. :rtype: typing.Callable[[T], T]
  117. """
  118. def wrapper(f):
  119. def wrapped(*args, **kwargs):
  120. return f(*args, **kwargs)
  121. wrapped.metadata = metadata
  122. wrapped.timeout = timeout
  123. return wrapped
  124. return wrapper