From d3cbc79dce27cb094de9e0ff5e1460f8dba6aae4 Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Fri, 25 Sep 2026 11:54:49 -0700 Subject: [PATCH] fix(bigquery): accept empty source_format fields --- .../google/cloud/bigquery/external_config.py | 8 ++++---- .../tests/unit/test_external_config.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/external_config.py b/packages/google-cloud-bigquery/google/cloud/bigquery/external_config.py index 7e76f93b57fe..1135a4494c87 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/external_config.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/external_config.py @@ -729,14 +729,14 @@ def __init__(self, source_format) -> None: self._properties = {"sourceFormat": source_format} @property - def source_format(self): - """:class:`~.external_config.ExternalSourceFormat`: + def source_format(self) -> Optional[str]: + """Optional[:class:`~.external_config.ExternalSourceFormat`]: Format of external source. See https://cloud.google.com/bigquery/docs/reference/rest/v2/tables#ExternalDataConfiguration.FIELDS.source_format """ - return self._properties["sourceFormat"] + return self._properties.get("sourceFormat") @property def options(self) -> Optional[OptionsType]: @@ -1120,7 +1120,7 @@ def from_api_repr(cls, resource: dict) -> "ExternalConfig": Returns: ExternalConfig: Configuration parsed from ``resource``. """ - config = cls(resource["sourceFormat"]) + config = cls(resource.get("sourceFormat")) config._properties = copy.deepcopy(resource) return config diff --git a/packages/google-cloud-bigquery/tests/unit/test_external_config.py b/packages/google-cloud-bigquery/tests/unit/test_external_config.py index ea827a560eec..201f1a8d52e3 100644 --- a/packages/google-cloud-bigquery/tests/unit/test_external_config.py +++ b/packages/google-cloud-bigquery/tests/unit/test_external_config.py @@ -81,6 +81,23 @@ def test_from_api_repr_base(self): got_resource = ec.to_api_repr() self.assertEqual(got_resource, resource) + def test_from_api_repr_missing_source_format(self): + resource = copy.deepcopy(self.BASE_RESOURCE) + del resource["sourceFormat"] + + ec = external_config.ExternalConfig.from_api_repr(resource) + self._verify_base(ec) + self.assertIsNone(ec.source_format) + self.assertIsNone(ec.options) + self.assertIsNone(ec.avro_options) + self.assertIsNone(ec.bigtable_options) + self.assertIsNone(ec.csv_options) + self.assertIsNone(ec.google_sheets_options) + self.assertIsNone(ec.parquet_options) + + got_resource = ec.to_api_repr() + self.assertEqual(got_resource, resource) + def test_to_api_repr_base(self): ec = external_config.ExternalConfig("") ec.source_uris = self.SOURCE_URIS