|
39 | 39 | import functools |
40 | 40 | import os |
41 | 41 | import uuid |
| 42 | +import textwrap |
42 | 43 | from typing import Any, Dict, Optional, TYPE_CHECKING, Union |
| 44 | +import warnings |
43 | 45 |
|
44 | 46 | import google.api_core.exceptions as core_exceptions |
45 | 47 | from google.api_core import retry as retries |
@@ -198,6 +200,44 @@ def _validate_job_config(request_body: Dict[str, Any], invalid_key: str): |
198 | 200 | raise ValueError(f"got unexpected key {repr(invalid_key)} in job_config") |
199 | 201 |
|
200 | 202 |
|
| 203 | +def validate_job_retry(job_id: Optional[str], job_retry: Optional[retries.Retry]): |
| 204 | + """Catch common mistakes, such as setting a job_id and job_retry at the same |
| 205 | + time. |
| 206 | + """ |
| 207 | + if job_id is not None and job_retry is not None: |
| 208 | + # TODO(tswast): To avoid breaking changes but still allow a default |
| 209 | + # query job retry, we currently only raise if they explicitly set a |
| 210 | + # job_retry other than the default. In a future version, we may want to |
| 211 | + # avoid this check for DEFAULT_JOB_RETRY and always raise. |
| 212 | + if job_retry is not google.cloud.bigquery.retry.DEFAULT_JOB_RETRY: |
| 213 | + raise TypeError( |
| 214 | + textwrap.dedent( |
| 215 | + """ |
| 216 | + `job_retry` was provided, but the returned job is |
| 217 | + not retryable, because a custom `job_id` was |
| 218 | + provided. To customize the job ID and allow for job |
| 219 | + retries, set job_id_prefix, instead. |
| 220 | + """ |
| 221 | + ).strip() |
| 222 | + ) |
| 223 | + else: |
| 224 | + warnings.warn( |
| 225 | + textwrap.dedent( |
| 226 | + """ |
| 227 | + job_retry must be explicitly set to None if job_id is set. |
| 228 | + BigQuery cannot retry a failed job by using the exact |
| 229 | + same ID. Setting job_id without explicitly disabling |
| 230 | + job_retry will raise an error in the future. To avoid this |
| 231 | + warning, either use job_id_prefix instead (preferred) or |
| 232 | + set job_retry=None. |
| 233 | + """ |
| 234 | + ).strip(), |
| 235 | + category=FutureWarning, |
| 236 | + # user code -> client.query / client.query_and_wait -> validate_job_retry |
| 237 | + stacklevel=3, |
| 238 | + ) |
| 239 | + |
| 240 | + |
201 | 241 | def _to_query_request( |
202 | 242 | job_config: Optional[job.QueryJobConfig] = None, |
203 | 243 | *, |
@@ -308,7 +348,7 @@ def query_jobs_query( |
308 | 348 | project: str, |
309 | 349 | retry: retries.Retry, |
310 | 350 | timeout: Optional[float], |
311 | | - job_retry: retries.Retry, |
| 351 | + job_retry: Optional[retries.Retry], |
312 | 352 | ) -> job.QueryJob: |
313 | 353 | """Initiate a query using jobs.query with jobCreationMode=JOB_CREATION_REQUIRED. |
314 | 354 |
|
|
0 commit comments