Skip to content

Commit ea6fbb9

Browse files
committed
Ability to use implicit lists and dicts
1 parent 643bc02 commit ea6fbb9

File tree

3 files changed

+71
-27
lines changed

3 files changed

+71
-27
lines changed

examples/query-service/basic_example.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ def main():
1616

1717
pool = ydb.QuerySessionPool(driver)
1818

19-
# print("=" * 50)
20-
# print("DELETE TABLE IF EXISTS")
21-
# pool.execute_with_retries("drop table if exists example")
19+
print("=" * 50)
20+
print("DELETE TABLE IF EXISTS")
21+
pool.execute_with_retries("drop table if exists example")
2222

23-
# print("=" * 50)
24-
# print("CREATE TABLE")
25-
# pool.execute_with_retries("CREATE TABLE example(key UInt64, value String, PRIMARY KEY (key))")
23+
print("=" * 50)
24+
print("CREATE TABLE")
25+
pool.execute_with_retries("CREATE TABLE example(key UInt64, value String, PRIMARY KEY (key))")
2626

27-
# pool.execute_with_retries("INSERT INTO example (key, value) VALUES (1, 'onepieceisreal')")
27+
pool.execute_with_retries("INSERT INTO example (key, value) VALUES (1, 'onepieceisreal')")
2828

2929
def callee(session):
3030
print("=" * 50)
@@ -94,7 +94,7 @@ def callee(session: ydb.QuerySessionSync):
9494

9595
for value in values:
9696
print(f"value: {value}")
97-
with session.transaction().execute(query=query_print, parameters={'$a': value}, commit_tx=True) as results:
97+
with session.transaction().execute(query=query_print, parameters={"$a": value}, commit_tx=True) as results:
9898
for result_set in results:
9999
print(f"rows: {str(result_set.rows)}")
100100

tests/query/test_query_parameters.py

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,50 +7,78 @@
77

88
def test_select_implicit_int(pool: ydb.QuerySessionPool):
99
expected_value = 111
10-
res = pool.execute_with_retries(query, parameters={'$a': expected_value})
11-
actual_value = res[0].rows[0]['value']
10+
res = pool.execute_with_retries(query, parameters={"$a": expected_value})
11+
actual_value = res[0].rows[0]["value"]
1212
assert expected_value == actual_value
1313

1414

1515
def test_select_implicit_float(pool: ydb.QuerySessionPool):
1616
expected_value = 11.1
17-
res = pool.execute_with_retries(query, parameters={'$a': expected_value})
18-
actual_value = res[0].rows[0]['value']
17+
res = pool.execute_with_retries(query, parameters={"$a": expected_value})
18+
actual_value = res[0].rows[0]["value"]
1919
assert expected_value == pytest.approx(actual_value)
2020

2121

2222
def test_select_implicit_bool(pool: ydb.QuerySessionPool):
2323
expected_value = False
24-
res = pool.execute_with_retries(query, parameters={'$a': expected_value})
25-
actual_value = res[0].rows[0]['value']
24+
res = pool.execute_with_retries(query, parameters={"$a": expected_value})
25+
actual_value = res[0].rows[0]["value"]
2626
assert expected_value == actual_value
2727

2828

2929
def test_select_implicit_str(pool: ydb.QuerySessionPool):
3030
expected_value = "text"
31-
res = pool.execute_with_retries(query, parameters={'$a': expected_value})
32-
actual_value = res[0].rows[0]['value']
31+
res = pool.execute_with_retries(query, parameters={"$a": expected_value})
32+
actual_value = res[0].rows[0]["value"]
33+
assert expected_value == actual_value
34+
35+
36+
def test_select_implicit_list(pool: ydb.QuerySessionPool):
37+
expected_value = [1, 2, 3]
38+
res = pool.execute_with_retries(query, parameters={"$a": expected_value})
39+
actual_value = res[0].rows[0]["value"]
40+
assert expected_value == actual_value
41+
42+
43+
def test_select_implicit_dict(pool: ydb.QuerySessionPool):
44+
expected_value = {"a": 1, "b": 2}
45+
res = pool.execute_with_retries(query, parameters={"$a": expected_value})
46+
actual_value = res[0].rows[0]["value"]
47+
assert expected_value == actual_value
48+
49+
50+
def test_select_implicit_list_nested(pool: ydb.QuerySessionPool):
51+
expected_value = [{"a": 1}, {"b": 2}]
52+
res = pool.execute_with_retries(query, parameters={"$a": expected_value})
53+
actual_value = res[0].rows[0]["value"]
54+
assert expected_value == actual_value
55+
56+
57+
def test_select_implicit_dict_nested(pool: ydb.QuerySessionPool):
58+
expected_value = {"a": [1, 2, 3], "b": [4, 5]}
59+
res = pool.execute_with_retries(query, parameters={"$a": expected_value})
60+
actual_value = res[0].rows[0]["value"]
3361
assert expected_value == actual_value
3462

3563

3664
def test_select_explicit_primitive(pool: ydb.QuerySessionPool):
3765
expected_value = 111
38-
res = pool.execute_with_retries(query, parameters={'$a': (expected_value, ydb.PrimitiveType.Int64)})
39-
actual_value = res[0].rows[0]['value']
66+
res = pool.execute_with_retries(query, parameters={"$a": (expected_value, ydb.PrimitiveType.Int64)})
67+
actual_value = res[0].rows[0]["value"]
4068
assert expected_value == actual_value
4169

4270

4371
def test_select_explicit_list(pool: ydb.QuerySessionPool):
4472
expected_value = [1, 2, 3]
4573
type_ = ydb.ListType(ydb.PrimitiveType.Int64)
46-
res = pool.execute_with_retries(query, parameters={'$a': (expected_value, type_)})
47-
actual_value = res[0].rows[0]['value']
74+
res = pool.execute_with_retries(query, parameters={"$a": (expected_value, type_)})
75+
actual_value = res[0].rows[0]["value"]
4876
assert expected_value == actual_value
4977

5078

5179
def test_select_explicit_dict(pool: ydb.QuerySessionPool):
52-
expected_value = {'key': 'value'}
80+
expected_value = {"key": "value"}
5381
type_ = ydb.DictType(ydb.PrimitiveType.Utf8, ydb.PrimitiveType.Utf8)
54-
res = pool.execute_with_retries(query, parameters={'$a': (expected_value, type_)})
55-
actual_value = res[0].rows[0]['value']
82+
res = pool.execute_with_retries(query, parameters={"$a": (expected_value, type_)})
83+
actual_value = res[0].rows[0]["value"]
5684
assert expected_value == actual_value

ydb/convert.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,17 +301,33 @@ def query_parameters_to_pb(parameters):
301301
_from_python_type_map = {
302302
int: types.PrimitiveType.Int64,
303303
float: types.PrimitiveType.Float,
304-
dict: types.PrimitiveType.Json,
305304
bool: types.PrimitiveType.Bool,
306305
str: types.PrimitiveType.Utf8,
307306
}
308307

309308

310309
def _primitive_type_from_python_native(value):
311310
t = type(value)
312-
if t not in _from_python_type_map:
313-
return types.PrimitiveType.Int64
314-
return _from_python_type_map[t]
311+
default_type = types.PrimitiveType.Int64
312+
313+
if t in _from_python_type_map:
314+
return _from_python_type_map[t]
315+
316+
if t == list:
317+
if len(value) == 0:
318+
return types.ListType(default_type)
319+
entry_type = _primitive_type_from_python_native(value[0])
320+
return types.ListType(entry_type)
321+
322+
if t == dict:
323+
if len(value) == 0:
324+
return types.DictType(default_type, default_type)
325+
entry = list(value.items())[0]
326+
key_type = _primitive_type_from_python_native(entry[0])
327+
value_type = _primitive_type_from_python_native(entry[1])
328+
return types.DictType(key_type, value_type)
329+
330+
return default_type
315331

316332

317333
def _unwrap_optionality(column):

0 commit comments

Comments
 (0)