Skip to content

Commit 4098386

Browse files
HemangChothaniplamut
authored andcommitted
feat(bigquery): add TypeError if wrong job_config type is passed to client job methods (googleapis#9506)
* feat(bigquery): raise TypeError if wrong job_config type is passed to client job methods * feat(bigquery): cosmetic changes * feat(bigquery): code refactor
1 parent 55a920e commit 4098386

3 files changed

Lines changed: 279 additions & 8 deletions

File tree

bigquery/google/cloud/bigquery/_helpers.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,3 +658,18 @@ def _build_resource_from_properties(obj, filter_fields):
658658
partial[filter_field] = obj._properties[filter_field]
659659

660660
return partial
661+
662+
663+
def _verify_job_config_type(job_config, expected_type, param_name="job_config"):
664+
if not isinstance(job_config, expected_type):
665+
msg = (
666+
"Expected an instance of {expected_type} class for the {param_name} parameter, "
667+
"but received {param_name} = {job_config}"
668+
)
669+
raise TypeError(
670+
msg.format(
671+
expected_type=expected_type.__name__,
672+
param_name=param_name,
673+
job_config=job_config,
674+
)
675+
)

bigquery/google/cloud/bigquery/client.py

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353

5454
from google.cloud.bigquery._helpers import _record_field_to_json
5555
from google.cloud.bigquery._helpers import _str_or_none
56+
from google.cloud.bigquery._helpers import _verify_job_config_type
5657
from google.cloud.bigquery._http import Connection
5758
from google.cloud.bigquery import _pandas_helpers
5859
from google.cloud.bigquery.dataset import Dataset
@@ -1355,6 +1356,11 @@ def load_table_from_uri(
13551356
13561357
Returns:
13571358
google.cloud.bigquery.job.LoadJob: A new load job.
1359+
1360+
Raises:
1361+
TypeError:
1362+
If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.LoadJobConfig`
1363+
class.
13581364
"""
13591365
job_id = _make_job_id(job_id, job_id_prefix)
13601366

@@ -1370,6 +1376,10 @@ def load_table_from_uri(
13701376
source_uris = [source_uris]
13711377

13721378
destination = _table_arg_to_table_ref(destination, default_project=self.project)
1379+
1380+
if job_config:
1381+
_verify_job_config_type(job_config, google.cloud.bigquery.job.LoadJobConfig)
1382+
13731383
load_job = job.LoadJob(job_ref, source_uris, destination, self, job_config)
13741384
load_job._begin(retry=retry)
13751385

@@ -1436,6 +1446,10 @@ def load_table_from_file(
14361446
If ``size`` is not passed in and can not be determined, or if
14371447
the ``file_obj`` can be detected to be a file opened in text
14381448
mode.
1449+
1450+
TypeError:
1451+
If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.LoadJobConfig`
1452+
class.
14391453
"""
14401454
job_id = _make_job_id(job_id, job_id_prefix)
14411455

@@ -1447,6 +1461,8 @@ def load_table_from_file(
14471461

14481462
destination = _table_arg_to_table_ref(destination, default_project=self.project)
14491463
job_ref = job._JobReference(job_id, project=project, location=location)
1464+
if job_config:
1465+
_verify_job_config_type(job_config, google.cloud.bigquery.job.LoadJobConfig)
14501466
load_job = job.LoadJob(job_ref, None, destination, self, job_config)
14511467
job_resource = load_job.to_api_repr()
14521468

@@ -1545,16 +1561,22 @@ def load_table_from_dataframe(
15451561
If a usable parquet engine cannot be found. This method
15461562
requires :mod:`pyarrow` or :mod:`fastparquet` to be
15471563
installed.
1564+
TypeError:
1565+
If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.LoadJobConfig`
1566+
class.
15481567
"""
15491568
job_id = _make_job_id(job_id, job_id_prefix)
15501569

1551-
if job_config is None:
1552-
job_config = job.LoadJobConfig()
1553-
else:
1570+
if job_config:
1571+
_verify_job_config_type(job_config, google.cloud.bigquery.job.LoadJobConfig)
15541572
# Make a copy so that the job config isn't modified in-place.
15551573
job_config_properties = copy.deepcopy(job_config._properties)
15561574
job_config = job.LoadJobConfig()
15571575
job_config._properties = job_config_properties
1576+
1577+
else:
1578+
job_config = job.LoadJobConfig()
1579+
15581580
job_config.source_format = job.SourceFormat.PARQUET
15591581

15601582
if location is None:
@@ -1700,14 +1722,21 @@ def load_table_from_json(
17001722
17011723
Returns:
17021724
google.cloud.bigquery.job.LoadJob: A new load job.
1725+
1726+
Raises:
1727+
TypeError:
1728+
If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.LoadJobConfig`
1729+
class.
17031730
"""
17041731
job_id = _make_job_id(job_id, job_id_prefix)
17051732

1706-
if job_config is None:
1707-
job_config = job.LoadJobConfig()
1708-
else:
1733+
if job_config:
1734+
_verify_job_config_type(job_config, google.cloud.bigquery.job.LoadJobConfig)
17091735
# Make a copy so that the job config isn't modified in-place.
17101736
job_config = copy.deepcopy(job_config)
1737+
else:
1738+
job_config = job.LoadJobConfig()
1739+
17111740
job_config.source_format = job.SourceFormat.NEWLINE_DELIMITED_JSON
17121741

17131742
if job_config.schema is None:
@@ -1900,6 +1929,11 @@ def copy_table(
19001929
19011930
Returns:
19021931
google.cloud.bigquery.job.CopyJob: A new copy job instance.
1932+
1933+
Raises:
1934+
TypeError:
1935+
If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.CopyJobConfig`
1936+
class.
19031937
"""
19041938
job_id = _make_job_id(job_id, job_id_prefix)
19051939

@@ -1928,6 +1962,8 @@ def copy_table(
19281962

19291963
destination = _table_arg_to_table_ref(destination, default_project=self.project)
19301964

1965+
if job_config:
1966+
_verify_job_config_type(job_config, google.cloud.bigquery.job.CopyJobConfig)
19311967
copy_job = job.CopyJob(
19321968
job_ref, sources, destination, client=self, job_config=job_config
19331969
)
@@ -1985,6 +2021,11 @@ def extract_table(
19852021
19862022
Returns:
19872023
google.cloud.bigquery.job.ExtractJob: A new extract job instance.
2024+
2025+
Raises:
2026+
TypeError:
2027+
If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.ExtractJobConfig`
2028+
class.
19882029
"""
19892030
job_id = _make_job_id(job_id, job_id_prefix)
19902031

@@ -2000,6 +2041,10 @@ def extract_table(
20002041
if isinstance(destination_uris, six.string_types):
20012042
destination_uris = [destination_uris]
20022043

2044+
if job_config:
2045+
_verify_job_config_type(
2046+
job_config, google.cloud.bigquery.job.ExtractJobConfig
2047+
)
20032048
extract_job = job.ExtractJob(
20042049
job_ref, source, destination_uris, client=self, job_config=job_config
20052050
)
@@ -2049,6 +2094,11 @@ def query(
20492094
20502095
Returns:
20512096
google.cloud.bigquery.job.QueryJob: A new query job instance.
2097+
2098+
Raises:
2099+
TypeError:
2100+
If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.QueryJobConfig`
2101+
class.
20522102
"""
20532103
job_id = _make_job_id(job_id, job_id_prefix)
20542104

@@ -2060,6 +2110,9 @@ def query(
20602110

20612111
if self._default_query_job_config:
20622112
if job_config:
2113+
_verify_job_config_type(
2114+
job_config, google.cloud.bigquery.job.QueryJobConfig
2115+
)
20632116
# anything that's not defined on the incoming
20642117
# that is in the default,
20652118
# should be filled in with the default
@@ -2068,6 +2121,10 @@ def query(
20682121
self._default_query_job_config
20692122
)
20702123
else:
2124+
_verify_job_config_type(
2125+
self._default_query_job_config,
2126+
google.cloud.bigquery.job.QueryJobConfig,
2127+
)
20712128
job_config = self._default_query_job_config
20722129

20732130
job_ref = job._JobReference(job_id, project=project, location=location)

0 commit comments

Comments
 (0)