Skip to content

Commit

Permalink
Allow passing schema as dicts _helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
plamut committed Oct 28, 2019
1 parent 37db6c2 commit 323573e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
27 changes: 25 additions & 2 deletions bigquery/google/cloud/bigquery/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,21 +224,44 @@ def _row_tuple_from_json(row, schema):
Args:
row (Dict): A JSON response row to be converted.
schema (Tuple): A tuple of :class:`~google.cloud.bigquery.schema.SchemaField`.
schema (Sequence[Union[ \
Sequence[:class:`~google.cloud.bigquery.schema.SchemaField`], \
Sequence[Mapping[str, str]] \
]]): Specification of the field types in ``row``.
Returns:
Tuple: A tuple of data converted to native types.
"""
from google.cloud.bigquery.schema import _to_schema_fields

schema = _to_schema_fields(schema)

row_data = []
for field, cell in zip(schema, row["f"]):
row_data.append(_field_from_json(cell["v"], field))
return tuple(row_data)


def _rows_from_json(values, schema):
"""Convert JSON row data to rows with appropriate types."""
"""Convert JSON row data to rows with appropriate types.
Args:
values (Sequence[Dict]): The list of responses (JSON rows) to convert.
schema (Union[ \
Sequence[:class:`~google.cloud.bigquery.schema.SchemaField`], \
Sequence[Mapping[str, str]] \
]):
The table's schema. If given as a sequence of dicts, their content
must be compatible with
:meth:`~google.cloud.bigquery.schema.SchemaField.from_api_repr`.
Returns:
List[:class:`~google.cloud.bigquery.Row`]
"""
from google.cloud.bigquery import Row
from google.cloud.bigquery.schema import _to_schema_fields

schema = _to_schema_fields(schema)
field_to_index = _field_to_index_mapping(schema)
return [Row(_row_tuple_from_json(r, schema), field_to_index) for r in values]

Expand Down
28 changes: 26 additions & 2 deletions bigquery/tests/unit/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import decimal
import unittest

import mock


class Test_not_null(unittest.TestCase):
def _call_fut(self, value, field):
Expand Down Expand Up @@ -412,7 +414,8 @@ class Test_row_tuple_from_json(unittest.TestCase):
def _call_fut(self, row, schema):
from google.cloud.bigquery._helpers import _row_tuple_from_json

return _row_tuple_from_json(row, schema)
with _field_isinstance_patcher():
return _row_tuple_from_json(row, schema)

def test_w_single_scalar_column(self):
# SELECT 1 AS col
Expand Down Expand Up @@ -529,7 +532,8 @@ class Test_rows_from_json(unittest.TestCase):
def _call_fut(self, rows, schema):
from google.cloud.bigquery._helpers import _rows_from_json

return _rows_from_json(rows, schema)
with _field_isinstance_patcher():
return _rows_from_json(rows, schema)

def test_w_record_subfield(self):
from google.cloud.bigquery.table import Row
Expand Down Expand Up @@ -1023,3 +1027,23 @@ def __init__(self, mode, name="unknown", field_type="UNKNOWN", fields=()):
self.name = name
self.field_type = field_type
self.fields = fields


def _field_isinstance_patcher():
"""A patcher thank makes _Field instances seem like SchemaField instances.
"""
from google.cloud.bigquery.schema import SchemaField

def fake_isinstance(instance, target_class):
if instance.__class__.__name__ != "_Field":
return isinstance(instance, target_class) # pragma: NO COVER

# pretend that _Field() instances are actually instances of SchemaField
return target_class is SchemaField or (
isinstance(target_class, tuple) and SchemaField in target_class
)

patcher = mock.patch(
"google.cloud.bigquery.schema.isinstance", side_effect=fake_isinstance
)
return patcher

0 comments on commit 323573e

Please sign in to comment.