-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: Adds foreign_type_info attribute to table class and adds unit tests. #2126
base: main
Are you sure you want to change the base?
Conversation
For details, see: | ||
https://cloud.google.com/bigquery/docs/external-tables | ||
https://cloud.google.com/bigquery/docs/datasets-intro#external_datasets | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'll need some logic in the setter for schema to avoid overwriting the schema
property entirely. Instead, it'll need to be responsible for just schema.fields
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I'm not sure if this format will render well in the docs. We might just move all the contents under NOTE:
to after Table's schema.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not yet addressed Tim's comment here.
I spoke with Linchin about the note and with the revision I added, Sphinx should be able to handle the note with no problem.
google/cloud/bigquery/table.py
Outdated
https://cloud.google.com/bigquery/docs/datasets-intro#external_datasets | ||
""" | ||
|
||
prop = self._properties.get(self._PROPERTY_TO_API_FIELD["foreign_type_info"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if we are exposing this at the table level, it needs to be fetched from schema, still, right?
This is exactly the sort of thing the _get_sub_prop
(
def _get_sub_prop(container, keys, default=None): |
_set_sub_prop
(def _set_sub_prop(container, keys, value): |
We even use it in other Table
properties, such as project
:
python-bigquery/google/cloud/bigquery/table.py
Lines 175 to 177 in 54c8d07
return _helpers._get_sub_prop( | |
self._properties, self._PROPERTY_TO_API_FIELD["project"] | |
) |
prop = self._properties.get(self._PROPERTY_TO_API_FIELD["foreign_type_info"]) | |
prop = _helpers._get_sub_prop(self._properties, self._PROPERTY_TO_API_FIELD["foreign_type_info"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Complete.
google/cloud/bigquery/table.py
Outdated
@@ -411,6 +412,7 @@ class Table(_TableBase): | |||
"max_staleness": "maxStaleness", | |||
"resource_tags": "resourceTags", | |||
"external_catalog_table_options": "externalCatalogTableOptions", | |||
"foreign_type_info": "foreignTypeInfo", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should adjust this to the format used for _helpers._get_sub_prop
and _helpers._set_sub_prop
. Likewise, let's replace schema
with something compatible with that.
"foreign_type_info": "foreignTypeInfo", | |
"foreign_type_info": ["schema", "foreignTypeInfo"], | |
# TODO: remove "schema" from above (between time_partitioning and "snapshot_definition" | |
"schema": ["schema", "fields"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partially complete. Added a new value for schema
, but not yet done with foreign_type_info
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Complete.
@@ -5993,6 +5994,71 @@ def test_external_catalog_table_options_from_api_repr(self): | |||
assert result == expected | |||
|
|||
|
|||
class TestForeignTypeInfo: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also like to see a test where we do Table.from_api_repr
and Table.to_api_repr
so that we can visually compare that the correct schema.foreignTypeInfo
field of the REST API object is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet addressed.
tests/unit/test_table.py
Outdated
table = self._make_one(self.TABLEREF) | ||
assert table.foreign_type_info is None | ||
|
||
def test_foreign_type_info_valid_inputs(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we also add test cases for the setter for other supported types, i.e., dict and None
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet addressed.
@@ -978,10 +978,12 @@ def _build_resource_from_properties(obj, filter_fields): | |||
""" | |||
partial = {} | |||
for filter_field in filter_fields: | |||
api_field = obj._PROPERTY_TO_API_FIELD.get(filter_field) | |||
api_field = _get_sub_prop(obj._PROPERTY_TO_API_FIELD, filter_field) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused with this part. The key is the property name of the class (e.g. what is the name of the @property
in the Table
class). I don't think that should ever by a list.
google/cloud/bigquery/_helpers.py
Outdated
if isinstance(api_field, list): | ||
api_field = api_field[0] | ||
partial[api_field] = obj._properties.get(api_field) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should use _get_sub_prop
and _set_sub_prop
here? Since some overlap, I fear that the schema
dictionary from schema.fields
will overwrite the dictionary from schema.foreignTypeInfo
or vice versa.
if isinstance(api_field, list): | |
api_field = api_field[0] | |
partial[api_field] = obj._properties.get(api_field) | |
_set_sub_prop(partial, api_field, _get_sub_prop(obj._properties, api_field)) |
This PR adds support for the
foreign_type_info
attribute on the Table class and the associated tests.