Content-Length: 4983 | pFad | http://github.com/googleapis/google-cloud-python/pull/8083.patch
thub.com
From d02a07659386f9aa77be218bd536ad49042f6b9c Mon Sep 17 00:00:00 2001
From: Tim Swast
Date: Tue, 21 May 2019 09:52:03 -0700
Subject: [PATCH] Don't raise error when encountering unknown fields in Models
API.
As new fields are added, the JSON -> Protobuf conversion should not
fail. Instead, it should ignore unknown fields. So that this data is not
discarded, use _properties as is the convention in our REST libraries.
It's private, but can be used as a workaround to get access to fields
that haven't yet been added to the client library.
---
bigquery/google/cloud/bigquery/model.py | 20 ++++++++++++-------
bigquery/tests/unit/model/test_model.py | 16 +++++++++++++++
.../tests/unit/model/test_model_reference.py | 14 +++++++++++++
3 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/bigquery/google/cloud/bigquery/model.py b/bigquery/google/cloud/bigquery/model.py
index 8b29e4008558..4049a9232467 100644
--- a/bigquery/google/cloud/bigquery/model.py
+++ b/bigquery/google/cloud/bigquery/model.py
@@ -268,6 +268,9 @@ def from_api_repr(cls, resource):
google.cloud.bigquery.model.Model: Model parsed from ``resource``.
"""
this = cls(None)
+ # Keep a reference to the resource as a workaround to find unknown
+ # field values.
+ this._properties = resource
# Convert from millis-from-epoch to timestamp well-known type.
# TODO: Remove this hack once CL 238585470 hits prod.
@@ -279,12 +282,9 @@ def from_api_repr(cls, resource):
start_time = datetime_helpers.from_microseconds(1e3 * float(start_time))
training_run["startTime"] = datetime_helpers.to_rfc3339(start_time)
- this._proto = json_format.ParseDict(resource, types.Model())
- for key in six.itervalues(cls._PROPERTY_TO_API_FIELD):
- # Leave missing keys unset. This allows us to use setdefault in the
- # getters where we want a default value other than None.
- if key in resource:
- this._properties[key] = resource[key]
+ this._proto = json_format.ParseDict(
+ resource, types.Model(), ignore_unknown_fields=True
+ )
return this
def _build_resource(self, filter_fields):
@@ -304,6 +304,7 @@ class ModelReference(object):
def __init__(self):
self._proto = types.ModelReference()
+ self._properties = {}
@property
def project(self):
@@ -342,7 +343,12 @@ def from_api_repr(cls, resource):
Model reference parsed from ``resource``.
"""
ref = cls()
- ref._proto = json_format.ParseDict(resource, types.ModelReference())
+ # Keep a reference to the resource as a workaround to find unknown
+ # field values.
+ ref._properties = resource
+ ref._proto = json_format.ParseDict(
+ resource, types.ModelReference(), ignore_unknown_fields=True
+ )
return ref
@classmethod
diff --git a/bigquery/tests/unit/model/test_model.py b/bigquery/tests/unit/model/test_model.py
index 2086c333486d..b6d9756e15fe 100644
--- a/bigquery/tests/unit/model/test_model.py
+++ b/bigquery/tests/unit/model/test_model.py
@@ -165,6 +165,22 @@ def test_from_api_repr_w_minimal_resource(target_class):
assert len(got.label_columns) == 0
+def test_from_api_repr_w_unknown_fields(target_class):
+ from google.cloud.bigquery import ModelReference
+
+ resource = {
+ "modelReference": {
+ "projectId": "my-project",
+ "datasetId": "my_dataset",
+ "modelId": "my_model",
+ },
+ "thisFieldIsNotInTheProto": "just ignore me",
+ }
+ got = target_class.from_api_repr(resource)
+ assert got.reference == ModelReference.from_string("my-project.my_dataset.my_model")
+ assert got._properties is resource
+
+
@pytest.mark.parametrize(
"resource,filter_fields,expected",
[
diff --git a/bigquery/tests/unit/model/test_model_reference.py b/bigquery/tests/unit/model/test_model_reference.py
index 0145c76f6ad0..ff1d1df7d499 100644
--- a/bigquery/tests/unit/model/test_model_reference.py
+++ b/bigquery/tests/unit/model/test_model_reference.py
@@ -37,6 +37,20 @@ def test_from_api_repr(target_class):
assert got.path == "/projects/my-project/datasets/my_dataset/models/my_model"
+def test_from_api_repr_w_unknown_fields(target_class):
+ resource = {
+ "projectId": "my-project",
+ "datasetId": "my_dataset",
+ "modelId": "my_model",
+ "thisFieldIsNotInTheProto": "just ignore me",
+ }
+ got = target_class.from_api_repr(resource)
+ assert got.project == "my-project"
+ assert got.dataset_id == "my_dataset"
+ assert got.model_id == "my_model"
+ assert got._properties is resource
+
+
def test_to_api_repr(target_class):
ref = target_class.from_string("my-project.my_dataset.my_model")
got = ref.to_api_repr()
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/googleapis/google-cloud-python/pull/8083.patch
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy