Skip to content

Commit 00e86ec

Browse files
the data is not parsed any more (#400)
1 parent 687f8ca commit 00e86ec

File tree

3 files changed

+15
-120
lines changed

3 files changed

+15
-120
lines changed

neo4j/__init__.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,6 @@
5050
"Result",
5151
"ResultSummary",
5252
"SummaryCounters",
53-
"Plan",
54-
"ProfiledPlan",
55-
"Notification",
56-
"Position",
5753
"Query",
5854
"Session",
5955
"unit_of_work",
@@ -111,10 +107,6 @@
111107
from neo4j.work.summary import (
112108
ResultSummary,
113109
SummaryCounters,
114-
Plan,
115-
ProfiledPlan,
116-
Notification,
117-
Position,
118110
)
119111

120112

neo4j/work/summary.py

Lines changed: 8 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,16 @@ class ResultSummary:
4545
#: Dictionary of parameters passed with the statement.
4646
parameters = None
4747

48-
#: The type of query (``'r'`` = read-only, ``'rw'`` = read/write).
48+
#: A string that describes the type of query (``'r'`` = read-only, ``'rw'`` = read/write).
4949
query_type = None
5050

51-
#: A :class:`.Counters` instance. Counters for operations the query triggered.
51+
#: A :class:`neo4j.SummaryCounters` instance. Counters for operations the query triggered.
5252
counters = None
5353

54-
#: A :class:`.Plan` instance. This describes how the database will execute the query.
54+
#: Dictionary that describes how the database will execute the query.
5555
plan = None
5656

57-
#: A :class:`.ProfiledPlan` instance
57+
#: Dictionary that describes how the database executed the query.
5858
profile = None
5959

6060
#: The time it took for the server to have the result available. (milliseconds)
@@ -63,7 +63,7 @@ class ResultSummary:
6363
#: The time it took for the server to consume the result. (milliseconds)
6464
result_consumed_after = None
6565

66-
#: A list of :class: `.Notification` instances
66+
#: A list of Dictionaries containing notification information.
6767
#: Notifications provide extra information for a user executing a statement.
6868
#: They can be warnings about problematic queries or other valuable information that can be
6969
#: presented in a client.
@@ -77,25 +77,16 @@ def __init__(self, **metadata):
7777
self.query = metadata.get("query")
7878
self.parameters = metadata.get("parameters")
7979
self.query_type = metadata.get("type")
80+
self.plan = metadata.get("plan")
81+
self.profile = metadata.get("profile")
82+
self.notifications = metadata.get("notifications")
8083
self.counters = SummaryCounters(metadata.get("stats", {}))
8184
if self.server.protocol_version[0] < BOLT_VERSION_3:
8285
self.result_available_after = metadata.get("result_available_after")
8386
self.result_consumed_after = metadata.get("result_consumed_after")
8487
else:
8588
self.result_available_after = metadata.get("t_first")
8689
self.result_consumed_after = metadata.get("t_last")
87-
if "plan" in metadata:
88-
self.plan = _make_plan(metadata["plan"])
89-
if "profile" in metadata:
90-
self.profile = _make_plan(metadata["profile"])
91-
self.plan = self.profile
92-
self.notifications = []
93-
for notification in metadata.get("notifications", []):
94-
position = notification.get("position")
95-
if position is not None:
96-
position = Position(position["offset"], position["line"], position["column"])
97-
self.notifications.append(Notification(notification["code"], notification["title"],
98-
notification["description"], notification["severity"], position))
9990

10091

10192
class SummaryCounters:
@@ -159,68 +150,3 @@ def contains_updates(self):
159150
def contains_system_updates(self):
160151
"""True if the system database was updated, otherwise False."""
161152
return self.system_updates > 0
162-
163-
164-
#: A plan describes how the database will execute your statement.
165-
#:
166-
#: operator_type:
167-
#: the name of the operation performed by the plan
168-
#: identifiers:
169-
#: the list of identifiers used by this plan
170-
#: arguments:
171-
#: a dictionary of arguments used in the specific operation performed by the plan
172-
#: children:
173-
#: a list of sub-plans
174-
Plan = namedtuple("Plan", ("operator_type", "identifiers", "arguments", "children"))
175-
176-
#: A profiled plan describes how the database executed your statement.
177-
#:
178-
#: db_hits:
179-
#: the number of times this part of the plan touched the underlying data stores
180-
#: rows:
181-
#: the number of records this part of the plan produced
182-
ProfiledPlan = namedtuple("ProfiledPlan", Plan._fields + ("db_hits", "rows"))
183-
184-
#: Representation for notifications found when executing a statement. A
185-
#: notification can be visualized in a client pinpointing problems or
186-
#: other information about the statement.
187-
#:
188-
#: code:
189-
#: a notification code for the discovered issue.
190-
#: title:
191-
#: a short summary of the notification
192-
#: description:
193-
#: a long description of the notification
194-
#: severity:
195-
#: the severity level of the notification
196-
#: position:
197-
#: the position in the statement where this notification points to, if relevant.
198-
Notification = namedtuple("Notification", ("code", "title", "description", "severity", "position"))
199-
200-
#: A position within a statement, consisting of offset, line and column.
201-
#:
202-
#: offset:
203-
#: the character offset referred to by this position; offset numbers start at 0
204-
#: line:
205-
#: the line number referred to by the position; line numbers start at 1
206-
#: column:
207-
#: the column number referred to by the position; column numbers start at 1
208-
Position = namedtuple("Position", ("offset", "line", "column"))
209-
210-
211-
def _make_plan(plan_dict):
212-
""" Construct a Plan or ProfiledPlan from a dictionary of metadata values.
213-
214-
:param plan_dict:
215-
:return:
216-
"""
217-
operator_type = plan_dict["operatorType"]
218-
identifiers = plan_dict.get("identifiers", [])
219-
arguments = plan_dict.get("args", [])
220-
children = [_make_plan(child) for child in plan_dict.get("children", [])]
221-
if "dbHits" in plan_dict or "rows" in plan_dict:
222-
db_hits = plan_dict.get("dbHits", 0)
223-
rows = plan_dict.get("rows", 0)
224-
return ProfiledPlan(operator_type, identifiers, arguments, children, db_hits, rows)
225-
else:
226-
return Plan(operator_type, identifiers, arguments, children)

tests/integration/test_summary.py

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
from neo4j import (
2424
ResultSummary,
2525
SummaryCounters,
26-
Plan,
27-
ProfiledPlan,
28-
Notification,
29-
Position,
3026
GraphDatabase,
3127
)
3228
from neo4j.exceptions import (
@@ -37,12 +33,6 @@
3733
)
3834

3935

40-
def get_operator_type(op):
41-
# Fabric will suffix with db name, remove this to handle fabric on/off
42-
op = op.split("@")
43-
return op[0]
44-
45-
4636
def test_can_obtain_summary_after_consuming_result(session):
4737
# python -m pytest tests/integration/test_summary.py -s -v -k test_can_obtain_summary_after_consuming_result
4838

@@ -62,30 +52,24 @@ def test_no_plan_info(session):
6252

6353

6454
def test_can_obtain_plan_info(session):
55+
# python -m pytest tests/integration/test_summary.py -s -v -k test_can_obtain_plan_info
6556
result = session.run("EXPLAIN CREATE (n) RETURN n")
6657
summary = result.consume()
67-
plan = summary.plan
68-
assert get_operator_type(plan.operator_type) == "ProduceResults"
69-
assert plan.identifiers == ["n"]
70-
assert len(plan.children) == 1
58+
assert isinstance(summary.plan, dict)
7159

7260

7361
def test_can_obtain_profile_info(session):
62+
# python -m pytest tests/integration/test_summary.py -s -v -k test_can_obtain_profile_info
7463
result = session.run("PROFILE CREATE (n) RETURN n")
7564
summary = result.consume()
76-
profile = summary.profile
77-
assert profile.db_hits == 0
78-
assert profile.rows == 1
79-
assert get_operator_type(profile.operator_type) == "ProduceResults"
80-
assert profile.identifiers == ["n"]
81-
assert len(profile.children) == 1
65+
assert isinstance(summary.profile, dict)
8266

8367

8468
def test_no_notification_info(session):
69+
# python -m pytest tests/integration/test_summary.py -s -v -k test_no_notification_info
8570
result = session.run("CREATE (n) RETURN n")
8671
summary = result.consume()
87-
notifications = summary.notifications
88-
assert notifications == []
72+
assert summary.notifications is None
8973

9074

9175
def test_can_obtain_notification_info(session):
@@ -97,14 +81,7 @@ def test_can_obtain_notification_info(session):
9781
notifications = summary.notifications
9882
assert isinstance(notifications, list)
9983
assert len(notifications) == 1
100-
101-
notification = notifications[0]
102-
assert isinstance(notification, Notification)
103-
assert notification.code.startswith("Neo.ClientNotification") # "Neo.ClientNotification.Statement.CartesianProductWarning"
104-
assert isinstance(notification.title, str) # "This query builds a cartesian product between disconnected patterns."
105-
assert isinstance(notification.severity, str) # "WARNING"
106-
assert isinstance(notification.description, str)
107-
assert isinstance(notification.position, Position)
84+
assert isinstance(notifications[0], dict)
10885

10986

11087
def test_contains_time_information(session):

0 commit comments

Comments
 (0)