Skip to content

Commit f1b75ce

Browse files
feat: primitive params (#351)
feat: primitive params --------- Co-authored-by: Wey Gu <[email protected]>
1 parent 5d562fb commit f1b75ce

File tree

5 files changed

+69
-38
lines changed

5 files changed

+69
-38
lines changed

README.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,11 @@ params = {
137137
"ids": ["player100", "player101"], # second query
138138
}
139139

140-
result = client.execute_py_params(
141-
"RETURN abs($p1)+3 AS col1, (toBoolean($p2) AND false) AS col2, toLower($p3)+1 AS col3",
140+
resp = client.execute_py(
141+
"RETURN abs($p1)+3 AS col1, (toBoolean($p2) and false) AS col2, toLower($p3)+1 AS col3",
142142
params,
143143
)
144-
145-
result = client.execute_py_params(
144+
resp = client.execute_py(
146145
"MATCH (v) WHERE id(v) in $ids RETURN id(v) AS vertex_id",
147146
params,
148147
)

example/Params.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import time
2+
from typing import Any, Dict, List
23

34
from nebula3.gclient.net import ConnectionPool
45
from nebula3.Config import Config
56
from nebula3.common import ttypes
7+
from nebula3.data.ResultSet import ResultSet
68

79
# define a config
810
config = Config()
@@ -51,12 +53,11 @@
5153
"p4": ["Bob", "Lily"],
5254
}
5355

54-
resp = client.execute_py_params(
56+
resp = client.execute_py(
5557
"RETURN abs($p1)+3 AS col1, (toBoolean($p2) and false) AS col2, toLower($p3)+1 AS col3",
5658
params_premitive,
5759
)
58-
59-
resp = client.execute_py_params(
60+
resp = client.execute_py(
6061
"MATCH (v) WHERE id(v) in $p4 RETURN id(v) AS vertex_id",
6162
params_premitive,
6263
)

nebula3/gclient/net/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@
2020
from nebula3.gclient.net.Session import Session
2121
from nebula3.gclient.net.Connection import Connection
2222
from nebula3.gclient.net.ConnectionPool import ConnectionPool
23+
from nebula3.gclient.net.base import BaseExecutor, ExecuteError

nebula3/gclient/net/base.py

+29-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@
55
from nebula3.common.ttypes import ErrorCode, Value, NList, Date, Time, DateTime
66

77

8+
class ExecuteError(Exception):
9+
def __init__(self, stmt: str, param: Any, code: ErrorCode, msg: str):
10+
self.stmt = stmt
11+
self.param = param
12+
self.code = code
13+
self.msg = msg
14+
15+
def __str__(self):
16+
return (
17+
f"ExecuteError. err_code: {self.code}, err_msg: {self.msg}.\n"
18+
+ f"Statement: \n{self.stmt}\n"
19+
+ f"Parameter: \n{self.param}"
20+
)
21+
22+
823
class BaseExecutor:
924
@abstractmethod
1025
def execute_parameter(
@@ -24,11 +39,21 @@ def execute(self, stmt: str) -> ResultSet:
2439
def execute_json(self, stmt: str) -> bytes:
2540
return self.execute_json_with_parameter(stmt, None)
2641

27-
def execute_py_params(
28-
self, stmt: str, params: Optional[Dict[str, Any]]
29-
) -> ResultSet:
42+
def execute_py(
43+
self,
44+
stmt: str,
45+
params: Optional[Dict[str, Any]] = None,
46+
):
3047
"""**Recommended** Execute a statement with parameters in Python type instead of thrift type."""
31-
return self.execute_parameter(stmt, _build_byte_param(params))
48+
if params is None:
49+
result = self.execute_parameter(stmt, None)
50+
else:
51+
result = self.execute_parameter(stmt, _build_byte_param(params))
52+
53+
if not result.is_succeeded():
54+
raise ExecuteError(stmt, params, result.error_code(), result.error_msg())
55+
56+
return result
3257

3358

3459
def _build_byte_param(params: dict) -> dict:

tests/test_parameter.py

+32-27
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import time
99
import json
1010

11-
from nebula3.gclient.net import ConnectionPool
11+
from nebula3.gclient.net import ConnectionPool, ExecuteError
1212
from nebula3.Config import Config
1313
from nebula3.common import *
1414
from unittest import TestCase
@@ -94,18 +94,6 @@ def test_parameter(self):
9494
assert False == resp.row_values(0)[1].as_bool()
9595
assert "bob1" == resp.row_values(0)[2].as_string()
9696

97-
# same test with premitive params
98-
resp = client.execute_py_params(
99-
"RETURN abs($p1)+3 AS col1, (toBoolean($p2) and false) AS col2, toLower($p3)+1 AS col3",
100-
self.params_premitive,
101-
)
102-
assert resp.is_succeeded(), resp.error_msg()
103-
assert 1 == resp.row_size()
104-
names = ["col1", "col2", "col3"]
105-
assert names == resp.keys()
106-
assert 6 == resp.row_values(0)[0].as_int()
107-
assert False == resp.row_values(0)[1].as_bool()
108-
assert "bob1" == resp.row_values(0)[2].as_string()
10997
# test cypher parameter
11098
resp = client.execute_parameter(
11199
f"""MATCH (v:person)--() WHERE v.person.age>abs($p1)+3
@@ -126,21 +114,11 @@ def test_parameter(self):
126114
self.params,
127115
)
128116
assert not resp.is_succeeded()
129-
resp = client.execute_py_params(
130-
'$p1=go from "Bob" over like yield like._dst;',
131-
self.params_premitive,
132-
)
133-
assert not resp.is_succeeded()
134117
resp = client.execute_parameter(
135118
"go from $p3 over like yield like._dst;",
136119
self.params,
137120
)
138121
assert not resp.is_succeeded()
139-
resp = client.execute_py_params(
140-
"go from $p3 over like yield like._dst;",
141-
self.params_premitive,
142-
)
143-
assert not resp.is_succeeded()
144122
resp = client.execute_parameter(
145123
"fetch prop on person $p3 yield vertex as v",
146124
self.params,
@@ -162,12 +140,39 @@ def test_parameter(self):
162140
)
163141
assert not resp.is_succeeded()
164142

165-
resp = client.execute_py_params(
143+
# same test with premitive params
144+
resp = client.execute_py(
145+
"RETURN abs($p1)+3 AS col1, (toBoolean($p2) and false) AS col2, toLower($p3)+1 AS col3",
146+
self.params_premitive,
147+
).as_primitive()
148+
assert 1 == len(resp)
149+
assert ["col1", "col2", "col3"] == list(resp[0].keys())
150+
assert resp[0]["col1"] == 6
151+
assert resp[0]["col2"] == False
152+
assert resp[0]["col3"] == "bob1"
153+
try:
154+
resp = client.execute_py(
155+
'$p1=go from "Bob" over like yield like._dst;',
156+
self.params_premitive,
157+
)
158+
except ExecuteError:
159+
pass
160+
else:
161+
raise AssertionError("should raise exception")
162+
try:
163+
resp = client.execute_py(
164+
"go from $p3 over like yield like._dst;",
165+
self.params_premitive,
166+
)
167+
except ExecuteError:
168+
pass
169+
else:
170+
raise AssertionError("should raise exception")
171+
resp = client.execute_py(
166172
"MATCH (v) WHERE id(v) in $p4 RETURN id(v) AS vertex_id",
167173
self.params_premitive,
168-
)
169-
assert resp.is_succeeded(), resp.error_msg()
170-
assert 2 == resp.row_size()
174+
).as_primitive()
175+
assert 2 == len(resp)
171176

172177
def tearDown(self) -> None:
173178
client = self.pool.get_session("root", "nebula")

0 commit comments

Comments
 (0)