Skip to content

Commit 937eef8

Browse files
committed
Test JSON scalar to df
1 parent 5e2d713 commit 937eef8

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

test/test_json.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,87 @@ def test_to_json_python_param_with_homogeneous_list_uses_typed_binding(
155155

156156
assert normalized_query == query
157157
assert normalized_parameters == parameters
158+
159+
160+
def test_get_as_df_json_scalar(conn_db_empty: ConnDB) -> None:
161+
"""
162+
Scalar JSON values convert through get_as_df() as Python strings.
163+
164+
Covers non-null values, typed JSON nulls, and a mixed column in a single query.
165+
"""
166+
conn, _ = conn_db_empty
167+
df = conn.execute(
168+
"UNWIND ["
169+
'CAST(\'{"a": 1, "b": [2, 3]}\' AS JSON), '
170+
"CAST(NULL AS JSON), "
171+
"CAST('[1, 2, 3]' AS JSON)"
172+
"] AS j RETURN j"
173+
).get_as_df()
174+
175+
assert str(df["j"].dtype) == "object"
176+
assert df["j"].isna().tolist() == [False, True, False]
177+
178+
first = df["j"].iloc[0]
179+
assert isinstance(first, str)
180+
assert json.loads(first) == {"a": 1, "b": [2, 3]}
181+
182+
third = df["j"].iloc[2]
183+
assert isinstance(third, str)
184+
assert json.loads(third) == [1, 2, 3]
185+
186+
187+
def test_get_as_df_json_empty_result(conn_db_empty: ConnDB) -> None:
188+
"""
189+
An empty result over a JSON column builds the column without crashing.
190+
191+
convertToArrayType() runs during NPArrayWrapper construction, before any
192+
rows are iterated, so a zero-row JSON result is the minimal reproduction
193+
for the original dtype-selection crash.
194+
"""
195+
conn, _ = conn_db_empty
196+
conn.execute("CREATE NODE TABLE t (id SERIAL PRIMARY KEY, data JSON)")
197+
198+
df = conn.execute("MATCH (n:t) RETURN n.data AS data").get_as_df()
199+
200+
assert len(df) == 0
201+
assert str(df["data"].dtype) == "object"
202+
203+
204+
def test_get_as_df_json_extract(conn_db_empty: ConnDB) -> None:
205+
"""json_extract() produces a scalar JSON result that converts via get_as_df()."""
206+
conn, _ = conn_db_empty
207+
conn.execute("INSTALL json; LOAD json;")
208+
conn.execute("CREATE NODE TABLE t (id SERIAL PRIMARY KEY, data JSON)")
209+
210+
data = {"name": {"first": "Alice", "last": "Smith"}}
211+
conn.execute(
212+
"CREATE (n:t {data: to_json($data)})",
213+
parameters={"data": json.dumps(data)},
214+
)
215+
216+
df = conn.execute(
217+
"MATCH (n:t) RETURN json_extract(n.data, '$.name') AS name"
218+
).get_as_df()
219+
220+
assert str(df["name"].dtype) == "object"
221+
val = df["name"].iloc[0]
222+
assert isinstance(val, str)
223+
assert json.loads(val) == {"first": "Alice", "last": "Smith"}
224+
225+
226+
def test_get_as_df_json_list(conn_db_empty: ConnDB) -> None:
227+
"""JSON[] (LIST of JSON) columns keep their existing pandas behavior."""
228+
conn, _ = conn_db_empty
229+
conn.execute("INSTALL json; LOAD json;")
230+
conn.execute("CREATE NODE TABLE t (id SERIAL PRIMARY KEY, data JSON[])")
231+
232+
data = [{"x": 1}, {"x": 2}, {"x": 3}]
233+
conn.execute("CREATE (n:t {data: $d})", parameters={"d": data})
234+
235+
df = conn.execute("MATCH (n:t) RETURN n.data AS data").get_as_df()
236+
237+
assert str(df["data"].dtype) == "object"
238+
val = df["data"].iloc[0]
239+
assert isinstance(val, list)
240+
assert len(val) == 3
241+
assert all(isinstance(e, str) for e in val)

0 commit comments

Comments
 (0)