real-ladybug 0.0.1.dev1__cp312-cp312-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of real-ladybug might be problematic. Click here for more details.
- real_ladybug/__init__.py +83 -0
- real_ladybug/_lbug.cp312-win_amd64.pyd +0 -0
- real_ladybug/_lbug.exp +0 -0
- real_ladybug/_lbug.lib +0 -0
- real_ladybug/async_connection.py +226 -0
- real_ladybug/connection.py +323 -0
- real_ladybug/constants.py +7 -0
- real_ladybug/database.py +307 -0
- real_ladybug/prepared_statement.py +51 -0
- real_ladybug/py.typed +0 -0
- real_ladybug/query_result.py +511 -0
- real_ladybug/torch_geometric_feature_store.py +185 -0
- real_ladybug/torch_geometric_graph_store.py +131 -0
- real_ladybug/torch_geometric_result_converter.py +282 -0
- real_ladybug/types.py +39 -0
- real_ladybug-0.0.1.dev1.dist-info/METADATA +88 -0
- real_ladybug-0.0.1.dev1.dist-info/RECORD +114 -0
- real_ladybug-0.0.1.dev1.dist-info/WHEEL +5 -0
- real_ladybug-0.0.1.dev1.dist-info/licenses/LICENSE +21 -0
- real_ladybug-0.0.1.dev1.dist-info/top_level.txt +3 -0
- real_ladybug-0.0.1.dev1.dist-info/zip-safe +1 -0
- real_ladybug-source/scripts/antlr4/hash.py +2 -0
- real_ladybug-source/scripts/antlr4/keywordhandler.py +47 -0
- real_ladybug-source/scripts/collect-extensions.py +68 -0
- real_ladybug-source/scripts/collect-single-file-header.py +126 -0
- real_ladybug-source/scripts/export-dbs.py +101 -0
- real_ladybug-source/scripts/export-import-test.py +345 -0
- real_ladybug-source/scripts/extension/purge-beta.py +34 -0
- real_ladybug-source/scripts/generate-cpp-docs/collect_files.py +122 -0
- real_ladybug-source/scripts/generate-tinysnb.py +34 -0
- real_ladybug-source/scripts/get-clangd-diagnostics.py +233 -0
- real_ladybug-source/scripts/migrate-lbug-db.py +308 -0
- real_ladybug-source/scripts/multiplatform-test-helper/collect-results.py +71 -0
- real_ladybug-source/scripts/multiplatform-test-helper/notify-discord.py +68 -0
- real_ladybug-source/scripts/pip-package/package_tar.py +90 -0
- real_ladybug-source/scripts/pip-package/setup.py +130 -0
- real_ladybug-source/scripts/run-clang-format.py +408 -0
- real_ladybug-source/scripts/setup-extension-repo.py +67 -0
- real_ladybug-source/scripts/test-simsimd-dispatch.py +45 -0
- real_ladybug-source/scripts/update-nightly-build-version.py +81 -0
- real_ladybug-source/third_party/brotli/scripts/dictionary/step-01-download-rfc.py +16 -0
- real_ladybug-source/third_party/brotli/scripts/dictionary/step-02-rfc-to-bin.py +34 -0
- real_ladybug-source/third_party/brotli/scripts/dictionary/step-03-validate-bin.py +35 -0
- real_ladybug-source/third_party/brotli/scripts/dictionary/step-04-generate-java-literals.py +85 -0
- real_ladybug-source/third_party/pybind11/tools/codespell_ignore_lines_from_errors.py +35 -0
- real_ladybug-source/third_party/pybind11/tools/libsize.py +36 -0
- real_ladybug-source/third_party/pybind11/tools/make_changelog.py +63 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/__init__.py +83 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/async_connection.py +226 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/connection.py +323 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/constants.py +7 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/database.py +307 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/prepared_statement.py +51 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/py.typed +0 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/query_result.py +511 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/torch_geometric_feature_store.py +185 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/torch_geometric_graph_store.py +131 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/torch_geometric_result_converter.py +282 -0
- real_ladybug-source/tools/python_api/build/real_ladybug/types.py +39 -0
- real_ladybug-source/tools/python_api/src_py/__init__.py +83 -0
- real_ladybug-source/tools/python_api/src_py/async_connection.py +226 -0
- real_ladybug-source/tools/python_api/src_py/connection.py +323 -0
- real_ladybug-source/tools/python_api/src_py/constants.py +7 -0
- real_ladybug-source/tools/python_api/src_py/database.py +307 -0
- real_ladybug-source/tools/python_api/src_py/prepared_statement.py +51 -0
- real_ladybug-source/tools/python_api/src_py/py.typed +0 -0
- real_ladybug-source/tools/python_api/src_py/query_result.py +511 -0
- real_ladybug-source/tools/python_api/src_py/torch_geometric_feature_store.py +185 -0
- real_ladybug-source/tools/python_api/src_py/torch_geometric_graph_store.py +131 -0
- real_ladybug-source/tools/python_api/src_py/torch_geometric_result_converter.py +282 -0
- real_ladybug-source/tools/python_api/src_py/types.py +39 -0
- real_ladybug-source/tools/python_api/test/conftest.py +230 -0
- real_ladybug-source/tools/python_api/test/disabled_test_extension.py +73 -0
- real_ladybug-source/tools/python_api/test/ground_truth.py +430 -0
- real_ladybug-source/tools/python_api/test/test_arrow.py +694 -0
- real_ladybug-source/tools/python_api/test/test_async_connection.py +159 -0
- real_ladybug-source/tools/python_api/test/test_blob_parameter.py +145 -0
- real_ladybug-source/tools/python_api/test/test_connection.py +49 -0
- real_ladybug-source/tools/python_api/test/test_database.py +234 -0
- real_ladybug-source/tools/python_api/test/test_datatype.py +372 -0
- real_ladybug-source/tools/python_api/test/test_df.py +564 -0
- real_ladybug-source/tools/python_api/test/test_dict.py +112 -0
- real_ladybug-source/tools/python_api/test/test_exception.py +54 -0
- real_ladybug-source/tools/python_api/test/test_fsm.py +227 -0
- real_ladybug-source/tools/python_api/test/test_get_header.py +49 -0
- real_ladybug-source/tools/python_api/test/test_helper.py +8 -0
- real_ladybug-source/tools/python_api/test/test_issue.py +147 -0
- real_ladybug-source/tools/python_api/test/test_iteration.py +96 -0
- real_ladybug-source/tools/python_api/test/test_networkx.py +437 -0
- real_ladybug-source/tools/python_api/test/test_parameter.py +340 -0
- real_ladybug-source/tools/python_api/test/test_prepared_statement.py +117 -0
- real_ladybug-source/tools/python_api/test/test_query_result.py +54 -0
- real_ladybug-source/tools/python_api/test/test_query_result_close.py +44 -0
- real_ladybug-source/tools/python_api/test/test_scan_pandas.py +676 -0
- real_ladybug-source/tools/python_api/test/test_scan_pandas_pyarrow.py +714 -0
- real_ladybug-source/tools/python_api/test/test_scan_polars.py +165 -0
- real_ladybug-source/tools/python_api/test/test_scan_pyarrow.py +167 -0
- real_ladybug-source/tools/python_api/test/test_timeout.py +11 -0
- real_ladybug-source/tools/python_api/test/test_torch_geometric.py +640 -0
- real_ladybug-source/tools/python_api/test/test_torch_geometric_remote_backend.py +111 -0
- real_ladybug-source/tools/python_api/test/test_udf.py +207 -0
- real_ladybug-source/tools/python_api/test/test_version.py +6 -0
- real_ladybug-source/tools/python_api/test/test_wal.py +80 -0
- real_ladybug-source/tools/python_api/test/type_aliases.py +10 -0
- real_ladybug-source/tools/rust_api/update_version.py +47 -0
- real_ladybug-source/tools/shell/test/conftest.py +218 -0
- real_ladybug-source/tools/shell/test/test_helper.py +60 -0
- real_ladybug-source/tools/shell/test/test_shell_basics.py +325 -0
- real_ladybug-source/tools/shell/test/test_shell_commands.py +656 -0
- real_ladybug-source/tools/shell/test/test_shell_control_edit.py +438 -0
- real_ladybug-source/tools/shell/test/test_shell_control_search.py +468 -0
- real_ladybug-source/tools/shell/test/test_shell_esc_edit.py +232 -0
- real_ladybug-source/tools/shell/test/test_shell_esc_search.py +162 -0
- real_ladybug-source/tools/shell/test/test_shell_flags.py +645 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
import polars as pl
|
|
4
|
+
import pytest
|
|
5
|
+
from type_aliases import ConnDB
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_polars_basic(conn_db_empty: ConnDB) -> None:
|
|
9
|
+
conn, _ = conn_db_empty
|
|
10
|
+
df = pl.DataFrame([
|
|
11
|
+
pl.Series("col1", [1, 2], dtype=pl.Int64),
|
|
12
|
+
pl.Series("col2", ["a", "b"], dtype=pl.String),
|
|
13
|
+
pl.Series("col3", [1.0, 2.0], dtype=pl.Float64),
|
|
14
|
+
pl.Series("col4", [datetime(2020, 5, 5), datetime(2000, 1, 1)], dtype=pl.Datetime),
|
|
15
|
+
])
|
|
16
|
+
result = conn.execute("LOAD FROM df RETURN *").get_as_pl()
|
|
17
|
+
equivalency = result == df
|
|
18
|
+
assert equivalency["col1"].all()
|
|
19
|
+
assert equivalency["col2"].all()
|
|
20
|
+
assert equivalency["col3"].all()
|
|
21
|
+
assert equivalency["col4"].all()
|
|
22
|
+
assert result["col1"].dtype == pl.Int64
|
|
23
|
+
assert result["col2"].dtype == pl.String
|
|
24
|
+
assert result["col3"].dtype == pl.Float64
|
|
25
|
+
assert result["col4"].dtype == pl.Datetime
|
|
26
|
+
# since polars just uses arrow as its backend, it's probably not necessary to extensively test this functionality
|
|
27
|
+
conn.execute(
|
|
28
|
+
"CREATE NODE TABLE polarstab(col1 INT64, col2 STRING, col3 DOUBLE, col4 TIMESTAMP, PRIMARY KEY(col1))"
|
|
29
|
+
)
|
|
30
|
+
conn.execute("COPY polarstab FROM df")
|
|
31
|
+
result = conn.execute(
|
|
32
|
+
"MATCH (t:polarstab) RETURN t.col1 AS col1, t.col2 AS col2, t.col3 AS col3, t.col4 AS col4 ORDER BY col1"
|
|
33
|
+
).get_as_pl()
|
|
34
|
+
equivalency = result == df
|
|
35
|
+
assert equivalency["col1"].all()
|
|
36
|
+
assert equivalency["col2"].all()
|
|
37
|
+
assert equivalency["col3"].all()
|
|
38
|
+
assert equivalency["col4"].all()
|
|
39
|
+
assert result["col1"].dtype == pl.Int64
|
|
40
|
+
assert result["col2"].dtype == pl.String
|
|
41
|
+
assert result["col3"].dtype == pl.Float64
|
|
42
|
+
assert result["col4"].dtype == pl.Datetime
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_polars_basic_param(conn_db_empty: ConnDB) -> None:
|
|
46
|
+
conn, _ = conn_db_empty
|
|
47
|
+
df = pl.DataFrame([
|
|
48
|
+
pl.Series("col1", [1, 2], dtype=pl.Int64),
|
|
49
|
+
pl.Series("col2", ["a", "b"], dtype=pl.String),
|
|
50
|
+
pl.Series("col3", [1.0, 2.0], dtype=pl.Float64),
|
|
51
|
+
pl.Series("col4", [datetime(2020, 5, 5), datetime(2000, 1, 1)], dtype=pl.Datetime),
|
|
52
|
+
])
|
|
53
|
+
result = conn.execute("LOAD FROM df RETURN *").get_as_pl()
|
|
54
|
+
equivalency = result == df
|
|
55
|
+
assert equivalency["col1"].all()
|
|
56
|
+
assert equivalency["col2"].all()
|
|
57
|
+
assert equivalency["col3"].all()
|
|
58
|
+
assert equivalency["col4"].all()
|
|
59
|
+
assert result["col1"].dtype == pl.Int64
|
|
60
|
+
assert result["col2"].dtype == pl.String
|
|
61
|
+
assert result["col3"].dtype == pl.Float64
|
|
62
|
+
assert result["col4"].dtype == pl.Datetime
|
|
63
|
+
# since polars just uses arrow as its backend, it's probably not necessary to extensively test this functionality
|
|
64
|
+
conn.execute(
|
|
65
|
+
"CREATE NODE TABLE polarstab(col1 INT64, col2 STRING, col3 DOUBLE, col4 TIMESTAMP, PRIMARY KEY(col1))"
|
|
66
|
+
)
|
|
67
|
+
conn.execute("COPY polarstab FROM $df", {"df": df})
|
|
68
|
+
result = conn.execute(
|
|
69
|
+
"MATCH (t:polarstab) RETURN t.col1 AS col1, t.col2 AS col2, t.col3 AS col3, t.col4 AS col4 ORDER BY col1"
|
|
70
|
+
).get_as_pl()
|
|
71
|
+
equivalency = result == df
|
|
72
|
+
assert equivalency["col1"].all()
|
|
73
|
+
assert equivalency["col2"].all()
|
|
74
|
+
assert equivalency["col3"].all()
|
|
75
|
+
assert equivalency["col4"].all()
|
|
76
|
+
assert result["col1"].dtype == pl.Int64
|
|
77
|
+
assert result["col2"].dtype == pl.String
|
|
78
|
+
assert result["col3"].dtype == pl.Float64
|
|
79
|
+
assert result["col4"].dtype == pl.Datetime
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_polars_error(conn_db_readonly: ConnDB) -> None:
|
|
83
|
+
conn, _ = conn_db_readonly
|
|
84
|
+
with pytest.raises(RuntimeError, match=r"Binder exception: Variable df is not in scope."):
|
|
85
|
+
conn.execute("LOAD FROM df RETURN *;")
|
|
86
|
+
df = []
|
|
87
|
+
with pytest.raises(
|
|
88
|
+
RuntimeError,
|
|
89
|
+
match=r"Binder exception: Attempted to scan from unsupported python object. Can only scan from pandas/polars dataframes and pyarrow tables.",
|
|
90
|
+
):
|
|
91
|
+
conn.execute("LOAD FROM df RETURN *;")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_polars_scan_ignore_errors(conn_db_empty: ConnDB) -> None:
|
|
95
|
+
conn, _ = conn_db_empty
|
|
96
|
+
df = pl.DataFrame({"id": [1, 2, 3, 1]})
|
|
97
|
+
conn.execute("CREATE NODE TABLE ids(id INT64, PRIMARY KEY(id))")
|
|
98
|
+
conn.execute("COPY ids FROM df(IGNORE_ERRORS=true)")
|
|
99
|
+
|
|
100
|
+
people = conn.execute("MATCH (i:ids) RETURN i.id")
|
|
101
|
+
assert people.get_next() == [1]
|
|
102
|
+
assert people.get_next() == [2]
|
|
103
|
+
assert people.get_next() == [3]
|
|
104
|
+
assert not people.has_next()
|
|
105
|
+
|
|
106
|
+
warnings = conn.execute("CALL show_warnings() RETURN *")
|
|
107
|
+
assert warnings.get_next()[1].startswith("Found duplicated primary key value 1")
|
|
108
|
+
assert not warnings.has_next()
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_copy_from_polars_multi_pairs(conn_db_empty: ConnDB) -> None:
|
|
112
|
+
conn, _ = conn_db_empty
|
|
113
|
+
conn.execute("CREATE NODE TABLE prof(id INT64, PRIMARY KEY(id))")
|
|
114
|
+
conn.execute("CREATE (p:prof {id: 3});")
|
|
115
|
+
conn.execute("CREATE (p:prof {id: 4});")
|
|
116
|
+
conn.execute("CREATE NODE TABLE student(id INT64, PRIMARY KEY(id))")
|
|
117
|
+
conn.execute("CREATE (p:student {id: 2});")
|
|
118
|
+
conn.execute("CREATE REL TABLE teaches(from prof to prof, from prof to student, length int64)")
|
|
119
|
+
df = pl.DataFrame({"from": [3], "to": [4], "length": [252]})
|
|
120
|
+
conn.execute("COPY teaches from df (from = 'prof', to = 'prof');")
|
|
121
|
+
result = conn.execute("match (:prof)-[e:teaches]->(:prof) return e.*")
|
|
122
|
+
assert result.has_next()
|
|
123
|
+
assert result.get_next()[0] == 252
|
|
124
|
+
assert not result.has_next()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_scan_from_empty_lst(conn_db_empty: ConnDB) -> None:
|
|
128
|
+
conn, _ = conn_db_empty
|
|
129
|
+
df = pl.DataFrame({"prop1": [3], "prop2": [[]]})
|
|
130
|
+
result = conn.execute("LOAD FROM df RETURN *")
|
|
131
|
+
assert result.has_next()
|
|
132
|
+
tp = result.get_next()
|
|
133
|
+
assert tp[0] == 3
|
|
134
|
+
assert tp[1] == []
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_scan_from_parameterized_df_docs_example_1(conn_db_empty: ConnDB):
|
|
138
|
+
conn, _ = conn_db_empty
|
|
139
|
+
|
|
140
|
+
conn.execute("CREATE NODE TABLE Person(name STRING, age INT64, PRIMARY KEY (name))")
|
|
141
|
+
|
|
142
|
+
df = pl.DataFrame({"name": ["Adam", "Karissa", "Zhang"], "age": [30, 40, 50]})
|
|
143
|
+
|
|
144
|
+
conn.execute("COPY Person FROM $dataframe", {"dataframe": df})
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_scan_from_parameterized_df_docs_example_2(conn_db_empty: ConnDB):
|
|
148
|
+
conn, _ = conn_db_empty
|
|
149
|
+
|
|
150
|
+
conn.execute("CREATE NODE TABLE Person(name STRING, age INT64, PRIMARY KEY (name))")
|
|
151
|
+
|
|
152
|
+
def get_df():
|
|
153
|
+
return pl.DataFrame({"name": ["Adam", "Karissa", "Zhang"], "age": [30, 40, 50]})
|
|
154
|
+
|
|
155
|
+
conn.execute("COPY Person FROM $dataframe", {"dataframe": get_df()})
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def test_scan_from_df_docs_example(conn_db_empty: ConnDB):
|
|
159
|
+
conn, _ = conn_db_empty
|
|
160
|
+
|
|
161
|
+
conn.execute("CREATE NODE TABLE Person(name STRING, age INT64, PRIMARY KEY (name))")
|
|
162
|
+
|
|
163
|
+
df = pl.DataFrame({"name": ["Adam", "Karissa", "Zhang"], "age": [30, 40, 50]})
|
|
164
|
+
|
|
165
|
+
conn.execute("COPY Person FROM df")
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import pyarrow as pa
|
|
2
|
+
import pytest
|
|
3
|
+
from type_aliases import ConnDB
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_pyarrow_basic(conn_db_readonly: ConnDB) -> None:
|
|
7
|
+
conn, _ = conn_db_readonly
|
|
8
|
+
tab = pa.Table.from_arrays(
|
|
9
|
+
[
|
|
10
|
+
[1, 2, 3],
|
|
11
|
+
["a", "b", "c"],
|
|
12
|
+
[True, False, None],
|
|
13
|
+
],
|
|
14
|
+
names=["col1", "col2", "col3"],
|
|
15
|
+
)
|
|
16
|
+
result = conn.execute("LOAD FROM tab RETURN * ORDER BY col1")
|
|
17
|
+
assert result.get_next() == [1, "a", True]
|
|
18
|
+
assert result.get_next() == [2, "b", False]
|
|
19
|
+
assert result.get_next() == [3, "c", None]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_pyarrow_copy_from_parameterized_df(conn_db_readwrite: ConnDB) -> None:
|
|
23
|
+
conn, _ = conn_db_readwrite
|
|
24
|
+
|
|
25
|
+
def get_tab_func():
|
|
26
|
+
return pa.Table.from_arrays(
|
|
27
|
+
[
|
|
28
|
+
pa.array([1, 2, 3], type=pa.int32()),
|
|
29
|
+
pa.array(["a", "b", "c"], type=pa.string()),
|
|
30
|
+
pa.array([True, False, None], type=pa.bool_()),
|
|
31
|
+
],
|
|
32
|
+
names=["id", "A", "B"],
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
conn.execute("CREATE NODE TABLE pyarrowtab(id INT32, A STRING, B BOOL, PRIMARY KEY(id))")
|
|
36
|
+
conn.execute("COPY pyarrowtab FROM $tab", {"tab": get_tab_func()})
|
|
37
|
+
result = conn.execute("MATCH (t:pyarrowtab) RETURN t.id AS id, t.A AS A, t.B AS B ORDER BY t.id")
|
|
38
|
+
assert result.get_next() == [1, "a", True]
|
|
39
|
+
assert result.get_next() == [2, "b", False]
|
|
40
|
+
assert result.get_next() == [3, "c", None]
|
|
41
|
+
|
|
42
|
+
rels = pa.Table.from_arrays(
|
|
43
|
+
[pa.array([1, 2, 3], type=pa.int32()), pa.array([2, 3, 1], type=pa.int32())], names=["from", "to"]
|
|
44
|
+
)
|
|
45
|
+
conn.execute("CREATE REL TABLE pyarrowrel(FROM pyarrowtab TO pyarrowtab)")
|
|
46
|
+
conn.execute("COPY pyarrowrel FROM $tab", {"tab": rels})
|
|
47
|
+
result = conn.execute("MATCH (a:pyarrowtab)-[:pyarrowrel]->(b:pyarrowtab) RETURN a.id, b.id ORDER BY a.id")
|
|
48
|
+
assert result.get_next() == [1, 2]
|
|
49
|
+
assert result.get_next() == [2, 3]
|
|
50
|
+
assert result.get_next() == [3, 1]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_pyarrow_copy_from_invalid_source(conn_db_readwrite: ConnDB) -> None:
|
|
54
|
+
conn, _ = conn_db_readwrite
|
|
55
|
+
conn.execute("CREATE NODE TABLE pyarrowtab(id INT32, A STRING, B BOOL, PRIMARY KEY(id))")
|
|
56
|
+
with pytest.raises(
|
|
57
|
+
RuntimeError,
|
|
58
|
+
match=r"Binder exception: Trying to scan from unsupported data type INT8\[\]. The only parameter types that can be scanned from are pandas/polars dataframes and pyarrow tables.",
|
|
59
|
+
):
|
|
60
|
+
conn.execute("COPY pyarrowtab FROM $tab", {"tab": [1, 2, 3]})
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_pyarrow_copy_from(conn_db_readwrite: ConnDB) -> None:
|
|
64
|
+
conn, _ = conn_db_readwrite
|
|
65
|
+
tab = pa.Table.from_arrays(
|
|
66
|
+
[
|
|
67
|
+
pa.array([1, 2, 3], type=pa.int32()),
|
|
68
|
+
pa.array(["a", "b", "c"], type=pa.string()),
|
|
69
|
+
pa.array([True, False, None], type=pa.bool_()),
|
|
70
|
+
],
|
|
71
|
+
names=["id", "A", "B"],
|
|
72
|
+
)
|
|
73
|
+
conn.execute("CREATE NODE TABLE pyarrowtab(id INT32, A STRING, B BOOL, PRIMARY KEY(id))")
|
|
74
|
+
conn.execute("COPY pyarrowtab FROM tab")
|
|
75
|
+
result = conn.execute("MATCH (t:pyarrowtab) RETURN t.id AS id, t.A AS A, t.B AS B ORDER BY t.id")
|
|
76
|
+
assert result.get_next() == [1, "a", True]
|
|
77
|
+
assert result.get_next() == [2, "b", False]
|
|
78
|
+
assert result.get_next() == [3, "c", None]
|
|
79
|
+
|
|
80
|
+
rels = pa.Table.from_arrays(
|
|
81
|
+
[pa.array([1, 2, 3], type=pa.int32()), pa.array([2, 3, 1], type=pa.int32())], names=["from", "to"]
|
|
82
|
+
)
|
|
83
|
+
conn.execute("CREATE REL TABLE pyarrowrel(FROM pyarrowtab TO pyarrowtab)")
|
|
84
|
+
conn.execute("COPY pyarrowrel FROM rels")
|
|
85
|
+
result = conn.execute("MATCH (a:pyarrowtab)-[:pyarrowrel]->(b:pyarrowtab) RETURN a.id, b.id ORDER BY a.id")
|
|
86
|
+
assert result.get_next() == [1, 2]
|
|
87
|
+
assert result.get_next() == [2, 3]
|
|
88
|
+
assert result.get_next() == [3, 1]
|
|
89
|
+
|
|
90
|
+
conn.execute("DROP TABLE pyarrowrel")
|
|
91
|
+
|
|
92
|
+
rels = pa.Table.from_arrays(
|
|
93
|
+
[
|
|
94
|
+
pa.array([1, 2, 3], type=pa.int32()),
|
|
95
|
+
pa.array([2, 3, 1], type=pa.int32()),
|
|
96
|
+
pa.array(["honk", "shoo", "mimimimimimimi"], type=pa.string()),
|
|
97
|
+
],
|
|
98
|
+
names=["foo", "bar", "spongebobmeboy"],
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
conn.execute("CREATE REL TABLE pyarrowrel(FROM pyarrowtab TO pyarrowtab, a_distraction STRING)")
|
|
102
|
+
conn.execute("COPY pyarrowrel FROM rels")
|
|
103
|
+
result = conn.execute(
|
|
104
|
+
"MATCH (a:pyarrowtab)-[r:pyarrowrel]->(b:pyarrowtab) RETURN a.id, r.a_distraction, b.id ORDER BY a.id"
|
|
105
|
+
)
|
|
106
|
+
assert result.get_next() == [1, "honk", 2]
|
|
107
|
+
assert result.get_next() == [2, "shoo", 3]
|
|
108
|
+
assert result.get_next() == [3, "mimimimimimimi", 1]
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_pyarrow_scan_ignore_errors(conn_db_readwrite: ConnDB) -> None:
|
|
112
|
+
conn, _ = conn_db_readwrite
|
|
113
|
+
tab = pa.Table.from_arrays(
|
|
114
|
+
[
|
|
115
|
+
pa.array([1, 2, 3, 1], type=pa.int32()),
|
|
116
|
+
],
|
|
117
|
+
names=["id"],
|
|
118
|
+
)
|
|
119
|
+
conn.execute("CREATE NODE TABLE ids(id INT64, PRIMARY KEY(id))")
|
|
120
|
+
conn.execute("COPY ids FROM tab(IGNORE_ERRORS=true)")
|
|
121
|
+
|
|
122
|
+
people = conn.execute("MATCH (i:ids) RETURN i.id")
|
|
123
|
+
assert people.get_next() == [1]
|
|
124
|
+
assert people.get_next() == [2]
|
|
125
|
+
assert people.get_next() == [3]
|
|
126
|
+
assert not people.has_next()
|
|
127
|
+
|
|
128
|
+
warnings = conn.execute("CALL show_warnings() RETURN *")
|
|
129
|
+
assert warnings.get_next()[1].startswith("Found duplicated primary key value 1")
|
|
130
|
+
assert not warnings.has_next()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_pyarrow_scan_invalid_option(conn_db_readwrite: ConnDB) -> None:
|
|
134
|
+
conn, _ = conn_db_readwrite
|
|
135
|
+
tab = pa.Table.from_arrays(
|
|
136
|
+
[
|
|
137
|
+
pa.array([1, 2, 3], type=pa.int32()),
|
|
138
|
+
],
|
|
139
|
+
names=["id"],
|
|
140
|
+
)
|
|
141
|
+
conn.execute("CREATE NODE TABLE ids(id INT64, PRIMARY KEY(id))")
|
|
142
|
+
error_message = "INVALID_OPTION Option not recognized by pyArrow scanner."
|
|
143
|
+
with pytest.raises(RuntimeError, match=error_message):
|
|
144
|
+
conn.execute("COPY ids FROM tab(INVALID_OPTION=1)")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_copy_from_pyarrow_multi_pairs(conn_db_readwrite: ConnDB) -> None:
|
|
148
|
+
conn, _ = conn_db_readwrite
|
|
149
|
+
conn.execute("CREATE NODE TABLE prof(id INT64, PRIMARY KEY(id))")
|
|
150
|
+
conn.execute("CREATE (p:prof {id: 3});")
|
|
151
|
+
conn.execute("CREATE (p:prof {id: 4});")
|
|
152
|
+
conn.execute("CREATE NODE TABLE student(id INT64, PRIMARY KEY(id))")
|
|
153
|
+
conn.execute("CREATE (p:student {id: 2});")
|
|
154
|
+
conn.execute("CREATE REL TABLE teaches(from prof to prof, from prof to student, length int64)")
|
|
155
|
+
df = pa.Table.from_arrays(
|
|
156
|
+
[
|
|
157
|
+
pa.array([3], type=pa.int64()),
|
|
158
|
+
pa.array([4], type=pa.int64()),
|
|
159
|
+
pa.array([252], type=pa.int64()),
|
|
160
|
+
],
|
|
161
|
+
names=["from", "to", "length"],
|
|
162
|
+
)
|
|
163
|
+
conn.execute("COPY teaches from df (from = 'prof', to = 'prof');")
|
|
164
|
+
result = conn.execute("match (:prof)-[e:teaches]->(:prof) return e.*")
|
|
165
|
+
assert result.has_next()
|
|
166
|
+
assert result.get_next()[0] == 252
|
|
167
|
+
assert not result.has_next()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from type_aliases import ConnDB
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_timeout(conn_db_readonly: ConnDB) -> None:
|
|
8
|
+
conn, _ = conn_db_readonly
|
|
9
|
+
conn.set_query_timeout(1000)
|
|
10
|
+
with pytest.raises(RuntimeError, match=r"Interrupted."):
|
|
11
|
+
conn.execute("UNWIND RANGE(1,100000) AS x UNWIND RANGE(1, 100000) AS y RETURN COUNT(x + y);")
|