Skip to content

Commit 92df09b

Browse files
author
Nigel Small
committed
Lazily fetch keys on request; fixes #33
Note that this changes ResultCursor.keys from a property to a method
1 parent 891db8b commit 92df09b

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

neo4j/v1/session.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def __init__(self, connection, statement, parameters):
129129
super(ResultCursor, self).__init__()
130130
self.statement = statement
131131
self.parameters = parameters
132-
self.keys = None
132+
self._keys = None
133133
self._connection = connection
134134
self._current = None
135135
self._next = deque()
@@ -156,7 +156,7 @@ def next(self):
156156
"""
157157
if self._next:
158158
values = self._next.popleft()
159-
self._current = Record(self.keys, tuple(map(hydrated, values)))
159+
self._current = Record(self.keys(), tuple(map(hydrated, values)))
160160
self._position += 1
161161
return True
162162
elif self._consumed:
@@ -199,6 +199,14 @@ def __getitem__(self, item):
199199
raise TypeError("No current record")
200200
return current[item]
201201

202+
def keys(self):
203+
""" Return the keys for the records.
204+
"""
205+
# Fetch messages until we have the header or a failure
206+
while self._keys is None and not self._consumed:
207+
self._connection.fetch_next()
208+
return self._keys
209+
202210
def get(self, item, default=None):
203211
current = self._current
204212
if current is None:
@@ -224,7 +232,7 @@ def _consume(self):
224232

225233
def _on_header(self, metadata):
226234
# Called on receipt of the result header.
227-
self.keys = metadata["fields"]
235+
self._keys = metadata["fields"]
228236

229237
def _on_record(self, values):
230238
# Called on receipt of each result record.

test/test_session.py

+13
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,19 @@ def test_can_obtain_notification_info(self):
261261
assert position.line == 1
262262
assert position.column == 1
263263

264+
def test_keys_are_available_before_and_after_stream(self):
265+
with GraphDatabase.driver("bolt://localhost").session() as session:
266+
cursor = session.run("UNWIND range(1, 10) AS n RETURN n")
267+
assert list(cursor.keys()) == ["n"]
268+
_ = list(cursor.stream())
269+
assert list(cursor.keys()) == ["n"]
270+
271+
def test_keys_with_an_error(self):
272+
with GraphDatabase.driver("bolt://localhost").session() as session:
273+
cursor = session.run("X")
274+
with self.assertRaises(CypherError):
275+
_ = list(cursor.keys())
276+
264277

265278
class ResetTestCase(TestCase):
266279

0 commit comments

Comments
 (0)