Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions bigquery/google/cloud/bigquery/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

"""Shared helper functions for BigQuery API classes."""

from collections import OrderedDict

from google.cloud._helpers import _datetime_from_microseconds
from google.cloud._helpers import _date_from_iso8601_date

Expand Down Expand Up @@ -402,26 +404,26 @@ class StructQueryParameter(AbstractQueryParameter):
:param name: Parameter name, used via ``@foo`` syntax. If None, the
paramter can only be addressed via position (``?``).

:type sub_parms: tuple of :class:`ScalarQueryParameter`
:param sub_parms: the sub-parameters for the struct
:type sub_params: tuple of :class:`ScalarQueryParameter`
:param sub_params: the sub-parameters for the struct
"""
def __init__(self, name, *sub_parms):
def __init__(self, name, *sub_params):
self.name = name
self._order = [sub.name for sub in sub_parms]
self.struct_types = {sub.name: sub.type_ for sub in sub_parms}
self.struct_values = {sub.name: sub.value for sub in sub_parms}
self.struct_types = OrderedDict(
(sub.name, sub.type_) for sub in sub_params)
self.struct_values = {sub.name: sub.value for sub in sub_params}

@classmethod
def positional(cls, *sub_parms):
def positional(cls, *sub_params):
"""Factory for positional paramters.

:type sub_parms: tuple of :class:`ScalarQueryParameter`
:param sub_parms: the sub-parameters for the struct
:type sub_params: tuple of :class:`ScalarQueryParameter`
:param sub_params: the sub-parameters for the struct

:rtype: :class:`StructQueryParameter`
:returns: instance without name
"""
return cls(None, *sub_parms)
return cls(None, *sub_params)

@classmethod
def from_api_repr(cls, resource):
Expand Down Expand Up @@ -452,8 +454,8 @@ def to_api_repr(self):
:returns: JSON mapping
"""
types = [
{'name': name, 'type': self.struct_types[name]}
for name in self._order
{'name': key, 'type': value}
for key, value in self.struct_types.items()

This comment was marked as spam.

This comment was marked as spam.

]
resource = {
'parameterType': {
Expand All @@ -472,13 +474,35 @@ class QueryParametersProperty(object):
"""Custom property type, holding query parameter instances."""

def __get__(self, instance, owner):
"""Descriptor protocol: accessor"""
"""Descriptor protocol: accessor

:type instance: :class:`QueryParametersProperty`
:param instance: instance owning the property (None if accessed via
the class).

:type owner: type
:param owner: the class owning the property.

:rtype: list of instances of classes derived from
:class:`AbstractQueryParameter`.
:returns: the descriptor, if accessed via the class, or the instance's
query paramters.
"""
if instance is None:
return self
return list(instance._query_parameters)

def __set__(self, instance, value):
"""Descriptor protocol: mutator"""
"""Descriptor protocol: mutator

:type instance: :class:`QueryParametersProperty`
:param instance: instance owning the property (None if accessed via
the class).

:type value: list of instances of classes derived from
:class:`AbstractQueryParameter`.

This comment was marked as spam.

This comment was marked as spam.

:param value: new query parameters for the instance.
"""
if not all(isinstance(u, AbstractQueryParameter) for u in value):

This comment was marked as spam.

This comment was marked as spam.

raise ValueError(
"query parameters must be derived from AbstractQueryParameter")
Expand Down
124 changes: 62 additions & 62 deletions bigquery/unit_tests/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,9 @@ def test_from_api_virtual(self):
klass.from_api_repr({})

def test_to_api_virtual(self):
parm = self._make_one()
param = self._make_one()
with self.assertRaises(NotImplementedError):
parm.to_api_repr()
param.to_api_repr()


class Test_ScalarQueryParameter(unittest.TestCase):
Expand All @@ -523,17 +523,17 @@ def _make_one(self, *args, **kw):
return self._get_target_class()(*args, **kw)

def test_ctor(self):
parm = self._make_one(name='foo', type_='INT64', value=123)
self.assertEqual(parm.name, 'foo')
self.assertEqual(parm.type_, 'INT64')
self.assertEqual(parm.value, 123)
param = self._make_one(name='foo', type_='INT64', value=123)
self.assertEqual(param.name, 'foo')
self.assertEqual(param.type_, 'INT64')
self.assertEqual(param.value, 123)

def test_positional(self):
klass = self._get_target_class()
parm = klass.positional(type_='INT64', value=123)
self.assertEqual(parm.name, None)
self.assertEqual(parm.type_, 'INT64')
self.assertEqual(parm.value, 123)
param = klass.positional(type_='INT64', value=123)
self.assertEqual(param.name, None)
self.assertEqual(param.type_, 'INT64')
self.assertEqual(param.value, 123)

def test_from_api_repr_w_name(self):
RESOURCE = {
Expand All @@ -546,10 +546,10 @@ def test_from_api_repr_w_name(self):
},
}
klass = self._get_target_class()
parm = klass.from_api_repr(RESOURCE)
self.assertEqual(parm.name, 'foo')
self.assertEqual(parm.type_, 'INT64')
self.assertEqual(parm.value, 123)
param = klass.from_api_repr(RESOURCE)
self.assertEqual(param.name, 'foo')
self.assertEqual(param.type_, 'INT64')
self.assertEqual(param.value, 123)

def test_from_api_repr_wo_name(self):
RESOURCE = {
Expand All @@ -561,10 +561,10 @@ def test_from_api_repr_wo_name(self):
},
}
klass = self._get_target_class()
parm = klass.from_api_repr(RESOURCE)
self.assertEqual(parm.name, None)
self.assertEqual(parm.type_, 'INT64')
self.assertEqual(parm.value, 123)
param = klass.from_api_repr(RESOURCE)
self.assertEqual(param.name, None)
self.assertEqual(param.type_, 'INT64')
self.assertEqual(param.value, 123)

def test_to_api_repr_w_name(self):
EXPECTED = {
Expand All @@ -576,8 +576,8 @@ def test_to_api_repr_w_name(self):
'value': 123,
},
}
parm = self._make_one(name='foo', type_='INT64', value=123)
self.assertEqual(parm.to_api_repr(), EXPECTED)
param = self._make_one(name='foo', type_='INT64', value=123)
self.assertEqual(param.to_api_repr(), EXPECTED)

def test_to_api_repr_wo_name(self):
EXPECTED = {
Expand All @@ -589,8 +589,8 @@ def test_to_api_repr_wo_name(self):
},
}
klass = self._get_target_class()
parm = klass.positional(type_='INT64', value=123)
self.assertEqual(parm.to_api_repr(), EXPECTED)
param = klass.positional(type_='INT64', value=123)
self.assertEqual(param.to_api_repr(), EXPECTED)


class Test_ArrayQueryParameter(unittest.TestCase):
Expand All @@ -604,17 +604,17 @@ def _make_one(self, *args, **kw):
return self._get_target_class()(*args, **kw)

def test_ctor(self):
parm = self._make_one(name='foo', array_type='INT64', values=[1, 2])
self.assertEqual(parm.name, 'foo')
self.assertEqual(parm.array_type, 'INT64')
self.assertEqual(parm.values, [1, 2])
param = self._make_one(name='foo', array_type='INT64', values=[1, 2])
self.assertEqual(param.name, 'foo')
self.assertEqual(param.array_type, 'INT64')
self.assertEqual(param.values, [1, 2])

def test_positional(self):
klass = self._get_target_class()
parm = klass.positional(array_type='INT64', values=[1, 2])
self.assertEqual(parm.name, None)
self.assertEqual(parm.array_type, 'INT64')
self.assertEqual(parm.values, [1, 2])
param = klass.positional(array_type='INT64', values=[1, 2])
self.assertEqual(param.name, None)
self.assertEqual(param.array_type, 'INT64')
self.assertEqual(param.values, [1, 2])

def test_from_api_repr_w_name(self):
RESOURCE = {
Expand All @@ -627,10 +627,10 @@ def test_from_api_repr_w_name(self):
},
}
klass = self._get_target_class()
parm = klass.from_api_repr(RESOURCE)
self.assertEqual(parm.name, 'foo')
self.assertEqual(parm.array_type, 'INT64')
self.assertEqual(parm.values, [1, 2])
param = klass.from_api_repr(RESOURCE)
self.assertEqual(param.name, 'foo')
self.assertEqual(param.array_type, 'INT64')
self.assertEqual(param.values, [1, 2])

def test_from_api_repr_wo_name(self):
RESOURCE = {
Expand All @@ -642,10 +642,10 @@ def test_from_api_repr_wo_name(self):
},
}
klass = self._get_target_class()
parm = klass.from_api_repr(RESOURCE)
self.assertEqual(parm.name, None)
self.assertEqual(parm.array_type, 'INT64')
self.assertEqual(parm.values, [1, 2])
param = klass.from_api_repr(RESOURCE)
self.assertEqual(param.name, None)
self.assertEqual(param.array_type, 'INT64')
self.assertEqual(param.values, [1, 2])

def test_to_api_repr_w_name(self):
EXPECTED = {
Expand All @@ -657,8 +657,8 @@ def test_to_api_repr_w_name(self):
'arrayValues': [1, 2],
},
}
parm = self._make_one(name='foo', array_type='INT64', values=[1, 2])
self.assertEqual(parm.to_api_repr(), EXPECTED)
param = self._make_one(name='foo', array_type='INT64', values=[1, 2])
self.assertEqual(param.to_api_repr(), EXPECTED)

def test_to_api_repr_wo_name(self):
EXPECTED = {
Expand All @@ -670,8 +670,8 @@ def test_to_api_repr_wo_name(self):
},
}
klass = self._get_target_class()
parm = klass.positional(array_type='INT64', values=[1, 2])
self.assertEqual(parm.to_api_repr(), EXPECTED)
param = klass.positional(array_type='INT64', values=[1, 2])
self.assertEqual(param.to_api_repr(), EXPECTED)


class Test_StructQueryParameter(unittest.TestCase):
Expand All @@ -692,19 +692,19 @@ def _make_subparam(name, type_, value):
def test_ctor(self):
sub_1 = self._make_subparam('bar', 'INT64', 123)
sub_2 = self._make_subparam('baz', 'STRING', 'abc')
parm = self._make_one('foo', sub_1, sub_2)
self.assertEqual(parm.name, 'foo')
self.assertEqual(parm.struct_types, {'bar': 'INT64', 'baz': 'STRING'})
self.assertEqual(parm.struct_values, {'bar': 123, 'baz': 'abc'})
param = self._make_one('foo', sub_1, sub_2)
self.assertEqual(param.name, 'foo')
self.assertEqual(param.struct_types, {'bar': 'INT64', 'baz': 'STRING'})
self.assertEqual(param.struct_values, {'bar': 123, 'baz': 'abc'})

def test_positional(self):
sub_1 = self._make_subparam('bar', 'INT64', 123)
sub_2 = self._make_subparam('baz', 'STRING', 'abc')
klass = self._get_target_class()
parm = klass.positional(sub_1, sub_2)
self.assertEqual(parm.name, None)
self.assertEqual(parm.struct_types, {'bar': 'INT64', 'baz': 'STRING'})
self.assertEqual(parm.struct_values, {'bar': 123, 'baz': 'abc'})
param = klass.positional(sub_1, sub_2)
self.assertEqual(param.name, None)
self.assertEqual(param.struct_types, {'bar': 'INT64', 'baz': 'STRING'})
self.assertEqual(param.struct_values, {'bar': 123, 'baz': 'abc'})

def test_from_api_repr_w_name(self):
RESOURCE = {
Expand All @@ -720,10 +720,10 @@ def test_from_api_repr_w_name(self):
},
}
klass = self._get_target_class()
parm = klass.from_api_repr(RESOURCE)
self.assertEqual(parm.name, 'foo')
self.assertEqual(parm.struct_types, {'bar': 'INT64', 'baz': 'STRING'})
self.assertEqual(parm.struct_values, {'bar': 123, 'baz': 'abc'})
param = klass.from_api_repr(RESOURCE)
self.assertEqual(param.name, 'foo')
self.assertEqual(param.struct_types, {'bar': 'INT64', 'baz': 'STRING'})
self.assertEqual(param.struct_values, {'bar': 123, 'baz': 'abc'})

def test_from_api_repr_wo_name(self):
RESOURCE = {
Expand All @@ -738,10 +738,10 @@ def test_from_api_repr_wo_name(self):
},
}
klass = self._get_target_class()
parm = klass.from_api_repr(RESOURCE)
self.assertEqual(parm.name, None)
self.assertEqual(parm.struct_types, {'bar': 'INT64', 'baz': 'STRING'})
self.assertEqual(parm.struct_values, {'bar': 123, 'baz': 'abc'})
param = klass.from_api_repr(RESOURCE)
self.assertEqual(param.name, None)
self.assertEqual(param.struct_types, {'bar': 'INT64', 'baz': 'STRING'})
self.assertEqual(param.struct_values, {'bar': 123, 'baz': 'abc'})

def test_to_api_repr_w_name(self):
EXPECTED = {
Expand All @@ -758,8 +758,8 @@ def test_to_api_repr_w_name(self):
}
sub_1 = self._make_subparam('bar', 'INT64', 123)
sub_2 = self._make_subparam('baz', 'STRING', 'abc')
parm = self._make_one('foo', sub_1, sub_2)
self.assertEqual(parm.to_api_repr(), EXPECTED)
param = self._make_one('foo', sub_1, sub_2)
self.assertEqual(param.to_api_repr(), EXPECTED)

def test_to_api_repr_wo_name(self):
EXPECTED = {
Expand All @@ -776,8 +776,8 @@ def test_to_api_repr_wo_name(self):
sub_1 = self._make_subparam('bar', 'INT64', 123)
sub_2 = self._make_subparam('baz', 'STRING', 'abc')
klass = self._get_target_class()
parm = klass.positional(sub_1, sub_2)
self.assertEqual(parm.to_api_repr(), EXPECTED)
param = klass.positional(sub_1, sub_2)
self.assertEqual(param.to_api_repr(), EXPECTED)


class Test_QueryParametersProperty(unittest.TestCase):
Expand Down
4 changes: 2 additions & 2 deletions bigquery/unit_tests/test_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -1287,7 +1287,7 @@ def _verifyIntegerResourceProperties(self, job, config):
else:
self.assertIsNone(job.maximum_bytes_billed)

def _verifyUDFResources(self, job, config):
def _verify_udf_resources(self, job, config):
udf_resources = config.get('userDefinedFunctionResources', ())
self.assertEqual(len(job.udf_resources), len(udf_resources))
for found, expected in zip(job.udf_resources, udf_resources):
Expand All @@ -1310,7 +1310,7 @@ def _verifyResourceProperties(self, job, resource):
config = resource.get('configuration', {}).get('query')
self._verifyBooleanResourceProperties(job, config)
self._verifyIntegerResourceProperties(job, config)
self._verifyUDFResources(job, config)
self._verify_udf_resources(job, config)
self._verifyQueryParameters(job, config)

self.assertEqual(job.query, config['query'])
Expand Down
4 changes: 2 additions & 2 deletions bigquery/unit_tests/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def _verifyRows(self, query, resource):
self.assertEqual(f_row,
tuple([cell['v'] for cell in e_row['f']]))

def _verifyUDFResources(self, query, resource):
def _verify_udf_resources(self, query, resource):
udf_resources = resource.get('userDefinedFunctionResources', ())
self.assertEqual(len(query.udf_resources), len(udf_resources))
for found, expected in zip(query.udf_resources, udf_resources):
Expand Down Expand Up @@ -131,7 +131,7 @@ def _verifyResourceProperties(self, query, resource):
else:
self.assertIsNone(query.name)

self._verifyUDFResources(query, resource)
self._verify_udf_resources(query, resource)
self._verifyQueryParameters(query, resource)
self._verifySchema(query, resource)
self._verifyRows(query, resource)
Expand Down
Loading