@@ -153,7 +153,196 @@ Closing a driver will immediately shut down all connections in the pool.
153
153
query, use :meth: `neo4j.Driver.verify_connectivity `.
154
154
155
155
.. autoclass :: neo4j.Driver()
156
- :members: session, encrypted, close, verify_connectivity, get_server_info
156
+ :members: session, query_bookmark_manager, encrypted, close,
157
+ verify_connectivity, get_server_info
158
+
159
+ .. 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)
160
+
161
+ Execute a query in a transaction function and return all results.
162
+
163
+ This method is a handy wrapper for lower-level driver APIs like
164
+ sessions, transactions, and transaction functions. It is intended
165
+ for simple use cases where there is no need for managing all possible
166
+ options.
167
+
168
+ The internal usage of transaction functions provides a retry-mechanism
169
+ for appropriate errors. Furthermore, this means that queries using
170
+ ``CALL {} IN TRANSACTIONS `` or the older ``USING PERIODIC COMMIT ``
171
+ will not work (use :meth: `Session.run ` for these).
172
+
173
+ The method is roughly equivalent to::
174
+
175
+ def execute_query(
176
+ query_, parameters_, routing_, database_, impersonated_user_,
177
+ bookmark_manager_, result_transformer_, **kwargs
178
+ ):
179
+ def work(tx):
180
+ result = tx.run(query_, parameters_, **kwargs)
181
+ return result_transformer_(result)
182
+
183
+ with driver.session(
184
+ database=database_,
185
+ impersonated_user=impersonated_user_,
186
+ bookmark_manager=bookmark_manager_,
187
+ ) as session:
188
+ if routing_ == RoutingControl.WRITERS:
189
+ return session.execute_write(work)
190
+ elif routing_ == RoutingControl.READERS:
191
+ return session.execute_read(work)
192
+
193
+ Usage example::
194
+
195
+ from typing import List
196
+
197
+ import neo4j
198
+
199
+
200
+ def example(driver: neo4j.Driver) -> List[str]:
201
+ \"""Get the name of all 42 year-olds.\"""
202
+ records, summary, keys = driver.execute_query(
203
+ "MATCH (p:Person {age: $age}) RETURN p.name",
204
+ {"age": 42},
205
+ routing_=neo4j.RoutingControl.READERS, # or just "r"
206
+ database_="neo4j",
207
+ )
208
+ assert keys == ["p.name"] # not needed, just for illustration
209
+ # log_summary(summary) # log some metadata
210
+ return [str(record["p.name"]) for record in records]
211
+ # or: return [str(record[0]) for record in records]
212
+ # or even: return list(map(lambda r: str(r[0]), records))
213
+
214
+ Another example::
215
+
216
+ import neo4j
217
+
218
+
219
+ def example(driver: neo4j.Driver) -> int:
220
+ \"""Call all young people "My dear" and get their count.\"""
221
+ record = driver.execute_query(
222
+ "MATCH (p:Person) WHERE p.age <= $age "
223
+ "SET p.nickname = 'My dear' "
224
+ "RETURN count(*)",
225
+ # optional routing parameter, as write is default
226
+ # routing_=neo4j.RoutingControl.WRITERS, # or just "w",
227
+ database_="neo4j",
228
+ result_transformer_=neo4j.Result.single,
229
+ age=15,
230
+ )
231
+ assert record is not None # for typechecking and illustration
232
+ count = record[0]
233
+ assert isinstance(count, int)
234
+ return count
235
+
236
+ :param query_: cypher query to execute
237
+ :type query_: typing.Optional[str]
238
+ :param parameters_: parameters to use in the query
239
+ :type parameters_: typing.Optional[typing.Dict[str, typing.Any]]
240
+ :param routing_:
241
+ whether to route the query to a reader (follower/read replica) or
242
+ a writer (leader) in the cluster. Default is to route to a writer.
243
+ :type routing_: neo4j.RoutingControl
244
+ :param database_:
245
+ database to execute the query against.
246
+
247
+ None (default) uses the database configured on the server side.
248
+
249
+ .. Note ::
250
+ It is recommended to always specify the database explicitly
251
+ when possible. This allows the driver to work more efficiently,
252
+ as it will not have to resolve the default database first.
253
+
254
+ See also the Session config :ref: `database-ref `.
255
+ :type database_: typing.Optional[str]
256
+ :param impersonated_user_:
257
+ Name of the user to impersonate.
258
+
259
+ This means that all query will be executed in the security context
260
+ of the impersonated user. For this, the user for which the
261
+ :class: `Driver ` has been created needs to have the appropriate
262
+ permissions.
263
+
264
+ See also the Session config :ref: `impersonated-user-ref `.
265
+ :type impersonated_user_: typing.Optional[str]
266
+ :param result_transformer_:
267
+ A function that gets passed the :class: `neo4j.Result ` object
268
+ resulting from the query and converts it to a different type. The
269
+ result of the transformer function is returned by this method.
270
+
271
+ .. warning ::
272
+
273
+ The transformer function must **not ** return the
274
+ :class: `neo4j.Result ` itself.
275
+
276
+ Example transformer that checks that exactly one record is in the
277
+ result stream, then returns the record and the result summary::
278
+
279
+ from typing import Tuple
280
+
281
+ import neo4j
282
+
283
+
284
+ def transformer(
285
+ result: neo4j.Result
286
+ ) -> Tuple[neo4j.Record, neo4j.ResultSummary]:
287
+ record = result.single(strict=True)
288
+ summary = result.consume()
289
+ return record, summary
290
+
291
+ Note that methods of :class: `neo4j.Result ` that don't take
292
+ mandatory arguments can be used directly as transformer functions.
293
+ For example::
294
+
295
+ import neo4j
296
+
297
+
298
+ def example(driver: neo4j.Driver) -> neo4j.Record::
299
+ record = driver.execute_query(
300
+ "SOME QUERY",
301
+ result_transformer_=neo4j.Result.single
302
+ )
303
+
304
+
305
+ # is equivalent to:
306
+
307
+
308
+ def transformer(result: neo4j.Result) -> neo4j.Record:
309
+ return result.single()
310
+
311
+
312
+ def example(driver: neo4j.Driver) -> neo4j.Record::
313
+ record = driver.execute_query(
314
+ "SOME QUERY",
315
+ result_transformer_=transformer
316
+ )
317
+
318
+ :type result_transformer_:
319
+ typing.Callable[[neo4j.Result], typing.Union[T]]
320
+ :param bookmark_manager_:
321
+ Specify a bookmark manager to use.
322
+
323
+ If present, the bookmark manager is used to keep the query causally
324
+ consistent with all work executed using the same bookmark manager.
325
+
326
+ Defaults to the driver's :attr: `.query_bookmark_manager `.
327
+
328
+ Pass :const: `None ` to disable causal consistency.
329
+ :type bookmark_manager_:
330
+ typing.Union[neo4j.BookmarkManager, neo4j.BookmarkManager,
331
+ None]
332
+ :param kwargs: additional keyword parameters. None of these can end
333
+ with a single underscore. This is to avoid collisions with the
334
+ keyword configuration parameters of this method. If you need to
335
+ pass such a parameter, use the ``parameters_ `` parameter instead.
336
+ These take precedence over parameters passed as ``parameters_ ``.
337
+ :type kwargs: typing.Any
338
+
339
+ :returns: the result of the ``result_transformer ``
340
+ :rtype: T
341
+
342
+ **This is experimental. ** (See :ref: `filter-warnings-ref `)
343
+ It might be changed or removed any time even without prior notice.
344
+
345
+ .. versionadded :: 5.5
157
346
158
347
159
348
.. _driver-configuration-ref :
@@ -974,11 +1163,22 @@ A :class:`neo4j.Result` is attached to an active connection, through a :class:`n
974
1163
975
1164
.. automethod :: to_df
976
1165
1166
+ .. automethod :: to_eager_result
1167
+
977
1168
.. automethod :: closed
978
1169
979
1170
See https://neo4j.com/docs/python-manual/current/cypher-workflow/#python-driver-type-mapping for more about type mapping.
980
1171
981
1172
1173
+ ***********
1174
+ EagerResult
1175
+ ***********
1176
+
1177
+ .. autoclass :: neo4j.EagerResult
1178
+ :show-inheritance:
1179
+ :members:
1180
+
1181
+
982
1182
Graph
983
1183
=====
984
1184
@@ -1370,15 +1570,17 @@ BookmarkManager
1370
1570
Constants, Enums, Helpers
1371
1571
*************************
1372
1572
1373
- .. autoclass :: neo4j.Address
1573
+ .. autoclass :: neo4j.RoutingControl
1374
1574
:show-inheritance:
1375
1575
:members:
1376
1576
1577
+ .. autoclass :: neo4j.Address
1578
+ :show-inheritance:
1579
+ :members:
1377
1580
1378
1581
.. autoclass :: neo4j.IPv4Address()
1379
1582
:show-inheritance:
1380
1583
1381
-
1382
1584
.. autoclass :: neo4j.IPv6Address()
1383
1585
:show-inheritance:
1384
1586
0 commit comments