Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 957f6e0

Browse filesBrowse files
Add SchemaField serialization and deserialization. (#3786)
1 parent 87a46a8 commit 957f6e0
Copy full SHA for 957f6e0

File tree

Expand file treeCollapse file tree

2 files changed

+82
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+82
-0
lines changed

‎bigquery/google/cloud/bigquery/schema.py

Copy file name to clipboardExpand all lines: bigquery/google/cloud/bigquery/schema.py
+41Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,25 @@ def __init__(self, name, field_type, mode='NULLABLE',
4343
self._description = description
4444
self._fields = tuple(fields)
4545

46+
@classmethod
47+
def from_api_repr(cls, api_repr):
48+
"""Return a ``SchemaField`` object deserialized from a dictionary.
49+
50+
Args:
51+
api_repr (Mapping[str, str]): The serialized representation
52+
of the SchemaField, such as what is output by
53+
:meth:`to_api_repr`.
54+
55+
Returns:
56+
SchemaField: The ``SchemaField`` object.
57+
"""
58+
return cls(
59+
field_type=api_repr['type'].upper(),
60+
fields=[cls.from_api_repr(f) for f in api_repr.get('fields', ())],
61+
mode=api_repr['mode'].upper(),
62+
name=api_repr['name'],
63+
)
64+
4665
@property
4766
def name(self):
4867
"""str: The name of the field."""
@@ -84,6 +103,28 @@ def fields(self):
84103
"""
85104
return self._fields
86105

106+
def to_api_repr(self):
107+
"""Return a dictionary representing this schema field.
108+
109+
Returns:
110+
dict: A dictionary representing the SchemaField in a serialized
111+
form.
112+
"""
113+
# Put together the basic representation. See http://bit.ly/2hOAT5u.
114+
answer = {
115+
'mode': self.mode.lower(),
116+
'name': self.name,
117+
'type': self.field_type.lower(),
118+
}
119+
120+
# If this is a RECORD type, then sub-fields are also included,
121+
# add this to the serialized representation.
122+
if self.field_type.upper() == 'RECORD':
123+
answer['fields'] = [f.to_api_repr() for f in self.fields]
124+
125+
# Done; return the serialized dictionary.
126+
return answer
127+
87128
def _key(self):
88129
"""A tuple key that unique-ly describes this field.
89130

‎bigquery/tests/unit/test_schema.py

Copy file name to clipboardExpand all lines: bigquery/tests/unit/test_schema.py
+41Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,47 @@ def test_constructor_subfields(self):
6161
self.assertIs(field._fields[0], sub_field1)
6262
self.assertIs(field._fields[1], sub_field2)
6363

64+
def test_to_api_repr(self):
65+
field = self._make_one('foo', 'INTEGER', 'NULLABLE')
66+
self.assertEqual(field.to_api_repr(), {
67+
'mode': 'nullable',
68+
'name': 'foo',
69+
'type': 'integer',
70+
})
71+
72+
def test_to_api_repr_with_subfield(self):
73+
subfield = self._make_one('bar', 'INTEGER', 'NULLABLE')
74+
field = self._make_one('foo', 'RECORD', 'REQUIRED', fields=(subfield,))
75+
self.assertEqual(field.to_api_repr(), {
76+
'fields': [{
77+
'mode': 'nullable',
78+
'name': 'bar',
79+
'type': 'integer',
80+
}],
81+
'mode': 'required',
82+
'name': 'foo',
83+
'type': 'record',
84+
})
85+
86+
def test_from_api_repr(self):
87+
field = self._get_target_class().from_api_repr({
88+
'fields': [{
89+
'mode': 'nullable',
90+
'name': 'bar',
91+
'type': 'integer',
92+
}],
93+
'mode': 'required',
94+
'name': 'foo',
95+
'type': 'record',
96+
})
97+
self.assertEqual(field.name, 'foo')
98+
self.assertEqual(field.field_type, 'RECORD')
99+
self.assertEqual(field.mode, 'REQUIRED')
100+
self.assertEqual(len(field.fields), 1)
101+
self.assertEqual(field.fields[0].name, 'bar')
102+
self.assertEqual(field.fields[0].field_type, 'INTEGER')
103+
self.assertEqual(field.fields[0].mode, 'NULLABLE')
104+
64105
def test_name_property(self):
65106
name = 'lemon-ness'
66107
schema_field = self._make_one(name, 'INTEGER')

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.