Skip to content

Commit b1dd04d

Browse files
asthamohtazoercailarkee
authored
feat: add support for JSON type (#353)
* add support for JSON- proto changes * adding json support-synth tool * deleting synth.metadata * Revert "add support for JSON- proto changes" This reverts commit a2f111c. * json changes * json changes * json changes * sorting keys and adding separators * adding changes to system test case * removing extra spaces * lint changes * changes to test_session * changes for lint Co-authored-by: Zoe <[email protected]> Co-authored-by: larkee <[email protected]>
1 parent 0bd17bb commit b1dd04d

File tree

6 files changed

+64
-3
lines changed

6 files changed

+64
-3
lines changed

google/cloud/spanner_v1/_helpers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ def _parse_value_pb(value_pb, field_type):
244244
]
245245
elif type_code == TypeCode.NUMERIC:
246246
return decimal.Decimal(value_pb.string_value)
247+
elif type_code == TypeCode.JSON:
248+
return value_pb.string_value
247249
else:
248250
raise ValueError("Unknown type: %s" % (field_type,))
249251

google/cloud/spanner_v1/param_types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
DATE = Type(code=TypeCode.DATE)
2929
TIMESTAMP = Type(code=TypeCode.TIMESTAMP)
3030
NUMERIC = Type(code=TypeCode.NUMERIC)
31+
JSON = Type(code=TypeCode.JSON)
3132

3233

3334
def Array(element_type): # pylint: disable=invalid-name

google/cloud/spanner_v1/streamed.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ def _merge_struct(lhs, rhs, type_):
316316
TypeCode.STRUCT: _merge_struct,
317317
TypeCode.TIMESTAMP: _merge_string,
318318
TypeCode.NUMERIC: _merge_string,
319+
TypeCode.JSON: _merge_string,
319320
}
320321

321322

tests/_fixtures.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@
4545
timestamp_value TIMESTAMP,
4646
timestamp_array ARRAY<TIMESTAMP>,
4747
numeric_value NUMERIC,
48-
numeric_array ARRAY<NUMERIC>)
48+
numeric_array ARRAY<NUMERIC>,
49+
json_value JSON,
50+
json_array ARRAY<JSON>,
51+
)
4952
PRIMARY KEY (pkey);
5053
CREATE TABLE counters (
5154
name STRING(1024),

tests/system/test_session_api.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import struct
2020
import threading
2121
import time
22-
22+
import json
2323
import pytest
2424

2525
import grpc
@@ -43,6 +43,24 @@
4343
BYTES_2 = b"Ym9vdHM="
4444
NUMERIC_1 = decimal.Decimal("0.123456789")
4545
NUMERIC_2 = decimal.Decimal("1234567890")
46+
JSON_1 = json.dumps(
47+
{
48+
"sample_boolean": True,
49+
"sample_int": 872163,
50+
"sample float": 7871.298,
51+
"sample_null": None,
52+
"sample_string": "abcdef",
53+
"sample_array": [23, 76, 19],
54+
},
55+
sort_keys=True,
56+
separators=(",", ":"),
57+
)
58+
JSON_2 = json.dumps(
59+
{"sample_object": {"name": "Anamika", "id": 2635}},
60+
sort_keys=True,
61+
separators=(",", ":"),
62+
)
63+
4664
COUNTERS_TABLE = "counters"
4765
COUNTERS_COLUMNS = ("name", "value")
4866
ALL_TYPES_TABLE = "all_types"
@@ -64,8 +82,10 @@
6482
"timestamp_array",
6583
"numeric_value",
6684
"numeric_array",
85+
"json_value",
86+
"json_array",
6787
)
68-
EMULATOR_ALL_TYPES_COLUMNS = LIVE_ALL_TYPES_COLUMNS[:-2]
88+
EMULATOR_ALL_TYPES_COLUMNS = LIVE_ALL_TYPES_COLUMNS[:-4]
6989
AllTypesRowData = collections.namedtuple("AllTypesRowData", LIVE_ALL_TYPES_COLUMNS)
7090
AllTypesRowData.__new__.__defaults__ = tuple([None for colum in LIVE_ALL_TYPES_COLUMNS])
7191
EmulatorAllTypesRowData = collections.namedtuple(
@@ -88,6 +108,7 @@
88108
AllTypesRowData(pkey=107, timestamp_value=SOME_TIME),
89109
AllTypesRowData(pkey=108, timestamp_value=NANO_TIME),
90110
AllTypesRowData(pkey=109, numeric_value=NUMERIC_1),
111+
AllTypesRowData(pkey=110, json_value=JSON_1),
91112
# empty array values
92113
AllTypesRowData(pkey=201, int_array=[]),
93114
AllTypesRowData(pkey=202, bool_array=[]),
@@ -97,6 +118,7 @@
97118
AllTypesRowData(pkey=206, string_array=[]),
98119
AllTypesRowData(pkey=207, timestamp_array=[]),
99120
AllTypesRowData(pkey=208, numeric_array=[]),
121+
AllTypesRowData(pkey=209, json_array=[]),
100122
# non-empty array values, including nulls
101123
AllTypesRowData(pkey=301, int_array=[123, 456, None]),
102124
AllTypesRowData(pkey=302, bool_array=[True, False, None]),
@@ -106,6 +128,7 @@
106128
AllTypesRowData(pkey=306, string_array=["One", "Two", None]),
107129
AllTypesRowData(pkey=307, timestamp_array=[SOME_TIME, NANO_TIME, None]),
108130
AllTypesRowData(pkey=308, numeric_array=[NUMERIC_1, NUMERIC_2, None]),
131+
AllTypesRowData(pkey=309, json_array=[JSON_1, JSON_2, None]),
109132
)
110133
EMULATOR_ALL_TYPES_ROWDATA = (
111134
# all nulls
@@ -1867,6 +1890,12 @@ def test_execute_sql_w_numeric_bindings(not_emulator, sessions_database):
18671890
)
18681891

18691892

1893+
def test_execute_sql_w_json_bindings(not_emulator, sessions_database):
1894+
_bind_test_helper(
1895+
sessions_database, spanner_v1.TypeCode.JSON, JSON_1, [JSON_1, JSON_2],
1896+
)
1897+
1898+
18701899
def test_execute_sql_w_query_param_struct(sessions_database):
18711900
name = "Phred"
18721901
count = 123

tests/unit/test__helpers.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,17 @@ def test_w_numeric_precision_and_scale_invalid(self):
295295
ValueError, err_msg, lambda: self._callFUT(value),
296296
)
297297

298+
def test_w_json(self):
299+
import json
300+
from google.protobuf.struct_pb2 import Value
301+
302+
value = json.dumps(
303+
{"id": 27863, "Name": "Anamika"}, sort_keys=True, separators=(",", ":")
304+
)
305+
value_pb = self._callFUT(value)
306+
self.assertIsInstance(value_pb, Value)
307+
self.assertEqual(value_pb.string_value, value)
308+
298309

299310
class Test_make_list_value_pb(unittest.TestCase):
300311
def _callFUT(self, *args, **kw):
@@ -552,6 +563,20 @@ def test_w_numeric(self):
552563

553564
self.assertEqual(self._callFUT(value_pb, field_type), VALUE)
554565

566+
def test_w_json(self):
567+
import json
568+
from google.protobuf.struct_pb2 import Value
569+
from google.cloud.spanner_v1 import Type
570+
from google.cloud.spanner_v1 import TypeCode
571+
572+
VALUE = json.dumps(
573+
{"id": 27863, "Name": "Anamika"}, sort_keys=True, separators=(",", ":")
574+
)
575+
field_type = Type(code=TypeCode.JSON)
576+
value_pb = Value(string_value=VALUE)
577+
578+
self.assertEqual(self._callFUT(value_pb, field_type), VALUE)
579+
555580
def test_w_unknown_type(self):
556581
from google.protobuf.struct_pb2 import Value
557582
from google.cloud.spanner_v1 import Type

0 commit comments

Comments
 (0)