google-cloud-bigquery 3.31.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. google/cloud/bigquery/__init__.py +249 -0
  2. google/cloud/bigquery/_helpers.py +1102 -0
  3. google/cloud/bigquery/_http.py +47 -0
  4. google/cloud/bigquery/_job_helpers.py +600 -0
  5. google/cloud/bigquery/_pandas_helpers.py +1181 -0
  6. google/cloud/bigquery/_pyarrow_helpers.py +147 -0
  7. google/cloud/bigquery/_tqdm_helpers.py +137 -0
  8. google/cloud/bigquery/_versions_helpers.py +264 -0
  9. google/cloud/bigquery/client.py +4406 -0
  10. google/cloud/bigquery/dataset.py +1076 -0
  11. google/cloud/bigquery/dbapi/__init__.py +87 -0
  12. google/cloud/bigquery/dbapi/_helpers.py +522 -0
  13. google/cloud/bigquery/dbapi/connection.py +128 -0
  14. google/cloud/bigquery/dbapi/cursor.py +586 -0
  15. google/cloud/bigquery/dbapi/exceptions.py +58 -0
  16. google/cloud/bigquery/dbapi/types.py +96 -0
  17. google/cloud/bigquery/encryption_configuration.py +84 -0
  18. google/cloud/bigquery/enums.py +389 -0
  19. google/cloud/bigquery/exceptions.py +35 -0
  20. google/cloud/bigquery/external_config.py +1188 -0
  21. google/cloud/bigquery/format_options.py +147 -0
  22. google/cloud/bigquery/iam.py +38 -0
  23. google/cloud/bigquery/job/__init__.py +87 -0
  24. google/cloud/bigquery/job/base.py +1116 -0
  25. google/cloud/bigquery/job/copy_.py +282 -0
  26. google/cloud/bigquery/job/extract.py +271 -0
  27. google/cloud/bigquery/job/load.py +985 -0
  28. google/cloud/bigquery/job/query.py +2498 -0
  29. google/cloud/bigquery/magics/__init__.py +20 -0
  30. google/cloud/bigquery/magics/line_arg_parser/__init__.py +34 -0
  31. google/cloud/bigquery/magics/line_arg_parser/exceptions.py +25 -0
  32. google/cloud/bigquery/magics/line_arg_parser/lexer.py +200 -0
  33. google/cloud/bigquery/magics/line_arg_parser/parser.py +484 -0
  34. google/cloud/bigquery/magics/line_arg_parser/visitors.py +159 -0
  35. google/cloud/bigquery/magics/magics.py +776 -0
  36. google/cloud/bigquery/model.py +517 -0
  37. google/cloud/bigquery/opentelemetry_tracing.py +164 -0
  38. google/cloud/bigquery/py.typed +2 -0
  39. google/cloud/bigquery/query.py +1344 -0
  40. google/cloud/bigquery/retry.py +207 -0
  41. google/cloud/bigquery/routine/__init__.py +33 -0
  42. google/cloud/bigquery/routine/routine.py +744 -0
  43. google/cloud/bigquery/schema.py +896 -0
  44. google/cloud/bigquery/standard_sql.py +389 -0
  45. google/cloud/bigquery/table.py +3594 -0
  46. google/cloud/bigquery/version.py +15 -0
  47. google/cloud/bigquery_v2/__init__.py +56 -0
  48. google/cloud/bigquery_v2/types/__init__.py +54 -0
  49. google/cloud/bigquery_v2/types/encryption_config.py +48 -0
  50. google/cloud/bigquery_v2/types/model.py +1994 -0
  51. google/cloud/bigquery_v2/types/model_reference.py +57 -0
  52. google/cloud/bigquery_v2/types/standard_sql.py +156 -0
  53. google/cloud/bigquery_v2/types/table_reference.py +80 -0
  54. google_cloud_bigquery-3.31.0.dist-info/LICENSE +202 -0
  55. google_cloud_bigquery-3.31.0.dist-info/METADATA +203 -0
  56. google_cloud_bigquery-3.31.0.dist-info/RECORD +58 -0
  57. google_cloud_bigquery-3.31.0.dist-info/WHEEL +5 -0
  58. google_cloud_bigquery-3.31.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,4406 @@
1
+ # Copyright 2015 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Client for interacting with the Google BigQuery API."""
16
+
17
+ from __future__ import absolute_import
18
+ from __future__ import division
19
+
20
+ from collections import abc as collections_abc
21
+ import copy
22
+ import datetime
23
+ import functools
24
+ import gzip
25
+ import io
26
+ import itertools
27
+ import json
28
+ import math
29
+ import os
30
+ import tempfile
31
+ import typing
32
+ from typing import (
33
+ Any,
34
+ Dict,
35
+ IO,
36
+ Iterable,
37
+ Mapping,
38
+ List,
39
+ Optional,
40
+ Sequence,
41
+ Tuple,
42
+ Union,
43
+ )
44
+ import uuid
45
+ import warnings
46
+
47
+ import requests
48
+
49
+ from google import resumable_media # type: ignore
50
+ from google.resumable_media.requests import MultipartUpload # type: ignore
51
+ from google.resumable_media.requests import ResumableUpload
52
+
53
+ import google.api_core.client_options
54
+ import google.api_core.exceptions as core_exceptions
55
+ from google.api_core.iam import Policy
56
+ from google.api_core import page_iterator
57
+ from google.api_core import retry as retries
58
+ import google.cloud._helpers # type: ignore
59
+ from google.cloud import exceptions # pytype: disable=import-error
60
+ from google.cloud.client import ClientWithProject # type: ignore # pytype: disable=import-error
61
+
62
+ try:
63
+ from google.cloud.bigquery_storage_v1.services.big_query_read.client import (
64
+ DEFAULT_CLIENT_INFO as DEFAULT_BQSTORAGE_CLIENT_INFO,
65
+ )
66
+ except ImportError:
67
+ DEFAULT_BQSTORAGE_CLIENT_INFO = None # type: ignore
68
+
69
+
70
+ from google.auth.credentials import Credentials
71
+ from google.cloud.bigquery._http import Connection
72
+ from google.cloud.bigquery import _job_helpers
73
+ from google.cloud.bigquery import _pandas_helpers
74
+ from google.cloud.bigquery import _versions_helpers
75
+ from google.cloud.bigquery import enums
76
+ from google.cloud.bigquery import exceptions as bq_exceptions
77
+ from google.cloud.bigquery import job
78
+ from google.cloud.bigquery._helpers import _get_sub_prop
79
+ from google.cloud.bigquery._helpers import _record_field_to_json
80
+ from google.cloud.bigquery._helpers import _str_or_none
81
+ from google.cloud.bigquery._helpers import _verify_job_config_type
82
+ from google.cloud.bigquery._helpers import _get_bigquery_host
83
+ from google.cloud.bigquery._helpers import _DEFAULT_HOST
84
+ from google.cloud.bigquery._helpers import _DEFAULT_HOST_TEMPLATE
85
+ from google.cloud.bigquery._helpers import _DEFAULT_UNIVERSE
86
+ from google.cloud.bigquery._helpers import _validate_universe
87
+ from google.cloud.bigquery._helpers import _get_client_universe
88
+ from google.cloud.bigquery._helpers import TimeoutType
89
+ from google.cloud.bigquery._job_helpers import make_job_id as _make_job_id
90
+ from google.cloud.bigquery.dataset import Dataset
91
+ from google.cloud.bigquery.dataset import DatasetListItem
92
+ from google.cloud.bigquery.dataset import DatasetReference
93
+ from google.cloud.bigquery.enums import AutoRowIDs
94
+ from google.cloud.bigquery.format_options import ParquetOptions
95
+ from google.cloud.bigquery.job import (
96
+ CopyJob,
97
+ CopyJobConfig,
98
+ ExtractJob,
99
+ ExtractJobConfig,
100
+ LoadJob,
101
+ LoadJobConfig,
102
+ QueryJob,
103
+ QueryJobConfig,
104
+ )
105
+ from google.cloud.bigquery.model import Model
106
+ from google.cloud.bigquery.model import ModelReference
107
+ from google.cloud.bigquery.model import _model_arg_to_model_ref
108
+ from google.cloud.bigquery.opentelemetry_tracing import create_span
109
+ from google.cloud.bigquery.query import _QueryResults
110
+ from google.cloud.bigquery.retry import (
111
+ DEFAULT_JOB_RETRY,
112
+ DEFAULT_RETRY,
113
+ DEFAULT_TIMEOUT,
114
+ DEFAULT_GET_JOB_TIMEOUT,
115
+ POLLING_DEFAULT_VALUE,
116
+ )
117
+ from google.cloud.bigquery.routine import Routine
118
+ from google.cloud.bigquery.routine import RoutineReference
119
+ from google.cloud.bigquery.schema import SchemaField
120
+ from google.cloud.bigquery.table import _table_arg_to_table
121
+ from google.cloud.bigquery.table import _table_arg_to_table_ref
122
+ from google.cloud.bigquery.table import Table
123
+ from google.cloud.bigquery.table import TableListItem
124
+ from google.cloud.bigquery.table import TableReference
125
+ from google.cloud.bigquery.table import RowIterator
126
+
127
+ pyarrow = _versions_helpers.PYARROW_VERSIONS.try_import()
128
+ pandas = (
129
+ _versions_helpers.PANDAS_VERSIONS.try_import()
130
+ ) # mypy check fails because pandas import is outside module, there are type: ignore comments related to this
131
+
132
+
133
+ ResumableTimeoutType = Union[
134
+ None, float, Tuple[float, float]
135
+ ] # for resumable media methods
136
+
137
+ if typing.TYPE_CHECKING: # pragma: NO COVER
138
+ # os.PathLike is only subscriptable in Python 3.9+, thus shielding with a condition.
139
+ PathType = Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]
140
+ _DEFAULT_CHUNKSIZE = 100 * 1024 * 1024 # 100 MB
141
+ _MAX_MULTIPART_SIZE = 5 * 1024 * 1024
142
+ _DEFAULT_NUM_RETRIES = 6
143
+ _BASE_UPLOAD_TEMPLATE = "{host}/upload/bigquery/v2/projects/{project}/jobs?uploadType="
144
+ _MULTIPART_URL_TEMPLATE = _BASE_UPLOAD_TEMPLATE + "multipart"
145
+ _RESUMABLE_URL_TEMPLATE = _BASE_UPLOAD_TEMPLATE + "resumable"
146
+ _GENERIC_CONTENT_TYPE = "*/*"
147
+ _READ_LESS_THAN_SIZE = (
148
+ "Size {:d} was specified but the file-like object only had " "{:d} bytes remaining."
149
+ )
150
+ _NEED_TABLE_ARGUMENT = (
151
+ "The table argument should be a table ID string, Table, or TableReference"
152
+ )
153
+ _LIST_ROWS_FROM_QUERY_RESULTS_FIELDS = "jobReference,totalRows,pageToken,rows"
154
+
155
+ # In microbenchmarks, it's been shown that even in ideal conditions (query
156
+ # finished, local data), requests to getQueryResults can take 10+ seconds.
157
+ # In less-than-ideal situations, the response can take even longer, as it must
158
+ # be able to download a full 100+ MB row in that time. Don't let the
159
+ # connection timeout before data can be downloaded.
160
+ # https://github.com/googleapis/python-bigquery/issues/438
161
+ _MIN_GET_QUERY_RESULTS_TIMEOUT = 120
162
+
163
+ TIMEOUT_HEADER = "X-Server-Timeout"
164
+
165
+
166
+ class Project(object):
167
+ """Wrapper for resource describing a BigQuery project.
168
+
169
+ Args:
170
+ project_id (str): Opaque ID of the project
171
+
172
+ numeric_id (int): Numeric ID of the project
173
+
174
+ friendly_name (str): Display name of the project
175
+ """
176
+
177
+ def __init__(self, project_id, numeric_id, friendly_name):
178
+ self.project_id = project_id
179
+ self.numeric_id = numeric_id
180
+ self.friendly_name = friendly_name
181
+
182
+ @classmethod
183
+ def from_api_repr(cls, resource):
184
+ """Factory: construct an instance from a resource dict."""
185
+ return cls(resource["id"], resource["numericId"], resource["friendlyName"])
186
+
187
+
188
+ class Client(ClientWithProject):
189
+ """Client to bundle configuration needed for API requests.
190
+
191
+ Args:
192
+ project (Optional[str]):
193
+ Project ID for the project which the client acts on behalf of.
194
+ Will be passed when creating a dataset / job. If not passed,
195
+ falls back to the default inferred from the environment.
196
+ credentials (Optional[google.auth.credentials.Credentials]):
197
+ The OAuth2 Credentials to use for this client. If not passed
198
+ (and if no ``_http`` object is passed), falls back to the
199
+ default inferred from the environment.
200
+ _http (Optional[requests.Session]):
201
+ HTTP object to make requests. Can be any object that
202
+ defines ``request()`` with the same interface as
203
+ :meth:`requests.Session.request`. If not passed, an ``_http``
204
+ object is created that is bound to the ``credentials`` for the
205
+ current object.
206
+ This parameter should be considered private, and could change in
207
+ the future.
208
+ location (Optional[str]):
209
+ Default location for jobs / datasets / tables.
210
+ default_query_job_config (Optional[google.cloud.bigquery.job.QueryJobConfig]):
211
+ Default ``QueryJobConfig``.
212
+ Will be merged into job configs passed into the ``query`` method.
213
+ default_load_job_config (Optional[google.cloud.bigquery.job.LoadJobConfig]):
214
+ Default ``LoadJobConfig``.
215
+ Will be merged into job configs passed into the ``load_table_*`` methods.
216
+ client_info (Optional[google.api_core.client_info.ClientInfo]):
217
+ The client info used to send a user-agent string along with API
218
+ requests. If ``None``, then default info will be used. Generally,
219
+ you only need to set this if you're developing your own library
220
+ or partner tool.
221
+ client_options (Optional[Union[google.api_core.client_options.ClientOptions, Dict]]):
222
+ Client options used to set user options on the client. API Endpoint
223
+ should be set through client_options.
224
+
225
+ Raises:
226
+ google.auth.exceptions.DefaultCredentialsError:
227
+ Raised if ``credentials`` is not specified and the library fails
228
+ to acquire default credentials.
229
+ """
230
+
231
+ SCOPE = ("https://www.googleapis.com/auth/cloud-platform",) # type: ignore
232
+ """The scopes required for authenticating as a BigQuery consumer."""
233
+
234
+ def __init__(
235
+ self,
236
+ project: Optional[str] = None,
237
+ credentials: Optional[Credentials] = None,
238
+ _http: Optional[requests.Session] = None,
239
+ location: Optional[str] = None,
240
+ default_query_job_config: Optional[QueryJobConfig] = None,
241
+ default_load_job_config: Optional[LoadJobConfig] = None,
242
+ client_info: Optional[google.api_core.client_info.ClientInfo] = None,
243
+ client_options: Optional[
244
+ Union[google.api_core.client_options.ClientOptions, Dict[str, Any]]
245
+ ] = None,
246
+ ) -> None:
247
+ if client_options is None:
248
+ client_options = {}
249
+ if isinstance(client_options, dict):
250
+ client_options = google.api_core.client_options.from_dict(client_options)
251
+ # assert isinstance(client_options, google.api_core.client_options.ClientOptions)
252
+
253
+ super(Client, self).__init__(
254
+ project=project,
255
+ credentials=credentials,
256
+ client_options=client_options,
257
+ _http=_http,
258
+ )
259
+
260
+ kw_args: Dict[str, Any] = {"client_info": client_info}
261
+ bq_host = _get_bigquery_host()
262
+ kw_args["api_endpoint"] = bq_host if bq_host != _DEFAULT_HOST else None
263
+ client_universe = None
264
+ if client_options.api_endpoint:
265
+ api_endpoint = client_options.api_endpoint
266
+ kw_args["api_endpoint"] = api_endpoint
267
+ else:
268
+ client_universe = _get_client_universe(client_options)
269
+ if client_universe != _DEFAULT_UNIVERSE:
270
+ kw_args["api_endpoint"] = _DEFAULT_HOST_TEMPLATE.replace(
271
+ "{UNIVERSE_DOMAIN}", client_universe
272
+ )
273
+ # Ensure credentials and universe are not in conflict.
274
+ if hasattr(self, "_credentials") and client_universe is not None:
275
+ _validate_universe(client_universe, self._credentials)
276
+
277
+ self._connection = Connection(self, **kw_args)
278
+ self._location = location
279
+ self._default_load_job_config = copy.deepcopy(default_load_job_config)
280
+
281
+ # Use property setter so validation can run.
282
+ self.default_query_job_config = default_query_job_config
283
+
284
+ @property
285
+ def location(self):
286
+ """Default location for jobs / datasets / tables."""
287
+ return self._location
288
+
289
+ @property
290
+ def default_query_job_config(self) -> Optional[QueryJobConfig]:
291
+ """Default ``QueryJobConfig`` or ``None``.
292
+
293
+ Will be merged into job configs passed into the ``query`` or
294
+ ``query_and_wait`` methods.
295
+ """
296
+ return self._default_query_job_config
297
+
298
+ @default_query_job_config.setter
299
+ def default_query_job_config(self, value: Optional[QueryJobConfig]):
300
+ if value is not None:
301
+ _verify_job_config_type(
302
+ value, QueryJobConfig, param_name="default_query_job_config"
303
+ )
304
+ self._default_query_job_config = copy.deepcopy(value)
305
+
306
+ @property
307
+ def default_load_job_config(self):
308
+ """Default ``LoadJobConfig``.
309
+ Will be merged into job configs passed into the ``load_table_*`` methods.
310
+ """
311
+ return self._default_load_job_config
312
+
313
+ @default_load_job_config.setter
314
+ def default_load_job_config(self, value: LoadJobConfig):
315
+ self._default_load_job_config = copy.deepcopy(value)
316
+
317
+ def close(self):
318
+ """Close the underlying transport objects, releasing system resources.
319
+
320
+ .. note::
321
+
322
+ The client instance can be used for making additional requests even
323
+ after closing, in which case the underlying connections are
324
+ automatically re-created.
325
+ """
326
+ self._http._auth_request.session.close()
327
+ self._http.close()
328
+
329
+ def get_service_account_email(
330
+ self,
331
+ project: Optional[str] = None,
332
+ retry: retries.Retry = DEFAULT_RETRY,
333
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
334
+ ) -> str:
335
+ """Get the email address of the project's BigQuery service account
336
+
337
+ Example:
338
+
339
+ .. code-block:: python
340
+
341
+ from google.cloud import bigquery
342
+ client = bigquery.Client()
343
+ client.get_service_account_email()
344
+ # returns an email similar to: my_service_account@my-project.iam.gserviceaccount.com
345
+
346
+ Note:
347
+ This is the service account that BigQuery uses to manage tables
348
+ encrypted by a key in KMS.
349
+
350
+ Args:
351
+ project (Optional[str]):
352
+ Project ID to use for retreiving service account email.
353
+ Defaults to the client's project.
354
+ retry (Optional[google.api_core.retry.Retry]): How to retry the RPC.
355
+ timeout (Optional[float]):
356
+ The number of seconds to wait for the underlying HTTP transport
357
+ before using ``retry``.
358
+
359
+ Returns:
360
+ str:
361
+ service account email address
362
+
363
+ """
364
+ if project is None:
365
+ project = self.project
366
+ path = "/projects/%s/serviceAccount" % (project,)
367
+ span_attributes = {"path": path}
368
+ api_response = self._call_api(
369
+ retry,
370
+ span_name="BigQuery.getServiceAccountEmail",
371
+ span_attributes=span_attributes,
372
+ method="GET",
373
+ path=path,
374
+ timeout=timeout,
375
+ )
376
+ return api_response["email"]
377
+
378
+ def list_projects(
379
+ self,
380
+ max_results: Optional[int] = None,
381
+ page_token: Optional[str] = None,
382
+ retry: retries.Retry = DEFAULT_RETRY,
383
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
384
+ page_size: Optional[int] = None,
385
+ ) -> page_iterator.Iterator:
386
+ """List projects for the project associated with this client.
387
+
388
+ See
389
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/projects/list
390
+
391
+ Args:
392
+ max_results (Optional[int]):
393
+ Maximum number of projects to return.
394
+ Defaults to a value set by the API.
395
+
396
+ page_token (Optional[str]):
397
+ Token representing a cursor into the projects. If not passed,
398
+ the API will return the first page of projects. The token marks
399
+ the beginning of the iterator to be returned and the value of
400
+ the ``page_token`` can be accessed at ``next_page_token`` of the
401
+ :class:`~google.api_core.page_iterator.HTTPIterator`.
402
+
403
+ retry (Optional[google.api_core.retry.Retry]): How to retry the RPC.
404
+
405
+ timeout (Optional[float]):
406
+ The number of seconds to wait for the underlying HTTP transport
407
+ before using ``retry``.
408
+
409
+ page_size (Optional[int]):
410
+ Maximum number of projects to return in each page.
411
+ Defaults to a value set by the API.
412
+
413
+ Returns:
414
+ google.api_core.page_iterator.Iterator:
415
+ Iterator of :class:`~google.cloud.bigquery.client.Project`
416
+ accessible to the current client.
417
+ """
418
+ span_attributes = {"path": "/projects"}
419
+
420
+ def api_request(*args, **kwargs):
421
+ return self._call_api(
422
+ retry,
423
+ span_name="BigQuery.listProjects",
424
+ span_attributes=span_attributes,
425
+ *args,
426
+ timeout=timeout,
427
+ **kwargs,
428
+ )
429
+
430
+ return page_iterator.HTTPIterator(
431
+ client=self,
432
+ api_request=api_request,
433
+ path="/projects",
434
+ item_to_value=_item_to_project,
435
+ items_key="projects",
436
+ page_token=page_token,
437
+ max_results=max_results,
438
+ page_size=page_size,
439
+ )
440
+
441
+ def list_datasets(
442
+ self,
443
+ project: Optional[str] = None,
444
+ include_all: bool = False,
445
+ filter: Optional[str] = None,
446
+ max_results: Optional[int] = None,
447
+ page_token: Optional[str] = None,
448
+ retry: retries.Retry = DEFAULT_RETRY,
449
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
450
+ page_size: Optional[int] = None,
451
+ ) -> page_iterator.Iterator:
452
+ """List datasets for the project associated with this client.
453
+
454
+ See
455
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/list
456
+
457
+ Args:
458
+ project (Optional[str]):
459
+ Project ID to use for retreiving datasets. Defaults to the
460
+ client's project.
461
+ include_all (Optional[bool]):
462
+ True if results include hidden datasets. Defaults to False.
463
+ filter (Optional[str]):
464
+ An expression for filtering the results by label.
465
+ For syntax, see
466
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/list#body.QUERY_PARAMETERS.filter
467
+ max_results (Optional[int]):
468
+ Maximum number of datasets to return.
469
+ page_token (Optional[str]):
470
+ Token representing a cursor into the datasets. If not passed,
471
+ the API will return the first page of datasets. The token marks
472
+ the beginning of the iterator to be returned and the value of
473
+ the ``page_token`` can be accessed at ``next_page_token`` of the
474
+ :class:`~google.api_core.page_iterator.HTTPIterator`.
475
+ retry (Optional[google.api_core.retry.Retry]):
476
+ How to retry the RPC.
477
+ timeout (Optional[float]):
478
+ The number of seconds to wait for the underlying HTTP transport
479
+ before using ``retry``.
480
+ page_size (Optional[int]):
481
+ Maximum number of datasets to return per page.
482
+
483
+ Returns:
484
+ google.api_core.page_iterator.Iterator:
485
+ Iterator of :class:`~google.cloud.bigquery.dataset.DatasetListItem`.
486
+ associated with the project.
487
+ """
488
+ extra_params: Dict[str, Any] = {}
489
+ if project is None:
490
+ project = self.project
491
+ if include_all:
492
+ extra_params["all"] = True
493
+ if filter:
494
+ # TODO: consider supporting a dict of label -> value for filter,
495
+ # and converting it into a string here.
496
+ extra_params["filter"] = filter
497
+ path = "/projects/%s/datasets" % (project,)
498
+
499
+ span_attributes = {"path": path}
500
+
501
+ def api_request(*args, **kwargs):
502
+ return self._call_api(
503
+ retry,
504
+ span_name="BigQuery.listDatasets",
505
+ span_attributes=span_attributes,
506
+ *args,
507
+ timeout=timeout,
508
+ **kwargs,
509
+ )
510
+
511
+ return page_iterator.HTTPIterator(
512
+ client=self,
513
+ api_request=api_request,
514
+ path=path,
515
+ item_to_value=_item_to_dataset,
516
+ items_key="datasets",
517
+ page_token=page_token,
518
+ max_results=max_results,
519
+ extra_params=extra_params,
520
+ page_size=page_size,
521
+ )
522
+
523
+ def dataset(
524
+ self, dataset_id: str, project: Optional[str] = None
525
+ ) -> DatasetReference:
526
+ """Deprecated: Construct a reference to a dataset.
527
+
528
+ .. deprecated:: 1.24.0
529
+ Construct a
530
+ :class:`~google.cloud.bigquery.dataset.DatasetReference` using its
531
+ constructor or use a string where previously a reference object
532
+ was used.
533
+
534
+ As of ``google-cloud-bigquery`` version 1.7.0, all client methods
535
+ that take a
536
+ :class:`~google.cloud.bigquery.dataset.DatasetReference` or
537
+ :class:`~google.cloud.bigquery.table.TableReference` also take a
538
+ string in standard SQL format, e.g. ``project.dataset_id`` or
539
+ ``project.dataset_id.table_id``.
540
+
541
+ Args:
542
+ dataset_id (str): ID of the dataset.
543
+
544
+ project (Optional[str]):
545
+ Project ID for the dataset (defaults to the project of the client).
546
+
547
+ Returns:
548
+ google.cloud.bigquery.dataset.DatasetReference:
549
+ a new ``DatasetReference`` instance.
550
+ """
551
+ if project is None:
552
+ project = self.project
553
+
554
+ warnings.warn(
555
+ "Client.dataset is deprecated and will be removed in a future version. "
556
+ "Use a string like 'my_project.my_dataset' or a "
557
+ "cloud.google.bigquery.DatasetReference object, instead.",
558
+ PendingDeprecationWarning,
559
+ stacklevel=2,
560
+ )
561
+ return DatasetReference(project, dataset_id)
562
+
563
+ def _ensure_bqstorage_client(
564
+ self,
565
+ bqstorage_client: Optional[
566
+ "google.cloud.bigquery_storage.BigQueryReadClient"
567
+ ] = None,
568
+ client_options: Optional[google.api_core.client_options.ClientOptions] = None,
569
+ client_info: Optional[
570
+ "google.api_core.gapic_v1.client_info.ClientInfo"
571
+ ] = DEFAULT_BQSTORAGE_CLIENT_INFO,
572
+ ) -> Optional["google.cloud.bigquery_storage.BigQueryReadClient"]:
573
+ """Create a BigQuery Storage API client using this client's credentials.
574
+
575
+ Args:
576
+ bqstorage_client:
577
+ An existing BigQuery Storage client instance. If ``None``, a new
578
+ instance is created and returned.
579
+ client_options:
580
+ Custom options used with a new BigQuery Storage client instance
581
+ if one is created.
582
+ client_info:
583
+ The client info used with a new BigQuery Storage client
584
+ instance if one is created.
585
+
586
+ Returns:
587
+ A BigQuery Storage API client.
588
+ """
589
+
590
+ try:
591
+ bigquery_storage = _versions_helpers.BQ_STORAGE_VERSIONS.try_import(
592
+ raise_if_error=True
593
+ )
594
+ except bq_exceptions.BigQueryStorageNotFoundError:
595
+ warnings.warn(
596
+ "Cannot create BigQuery Storage client, the dependency "
597
+ "google-cloud-bigquery-storage is not installed."
598
+ )
599
+ return None
600
+ except bq_exceptions.LegacyBigQueryStorageError as exc:
601
+ warnings.warn(
602
+ "Dependency google-cloud-bigquery-storage is outdated: " + str(exc)
603
+ )
604
+ return None
605
+
606
+ if bqstorage_client is None: # pragma: NO COVER
607
+ bqstorage_client = bigquery_storage.BigQueryReadClient(
608
+ credentials=self._credentials,
609
+ client_options=client_options,
610
+ client_info=client_info, # type: ignore # (None is also accepted)
611
+ )
612
+
613
+ return bqstorage_client
614
+
615
+ def _dataset_from_arg(self, dataset) -> Union[Dataset, DatasetReference]:
616
+ if isinstance(dataset, str):
617
+ dataset = DatasetReference.from_string(
618
+ dataset, default_project=self.project
619
+ )
620
+
621
+ if not isinstance(dataset, (Dataset, DatasetReference)):
622
+ if isinstance(dataset, DatasetListItem):
623
+ dataset = dataset.reference
624
+ else:
625
+ raise TypeError(
626
+ "dataset must be a Dataset, DatasetReference, DatasetListItem,"
627
+ " or string"
628
+ )
629
+ return dataset
630
+
631
+ def create_dataset(
632
+ self,
633
+ dataset: Union[str, Dataset, DatasetReference, DatasetListItem],
634
+ exists_ok: bool = False,
635
+ retry: retries.Retry = DEFAULT_RETRY,
636
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
637
+ ) -> Dataset:
638
+ """API call: create the dataset via a POST request.
639
+
640
+
641
+ See
642
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/insert
643
+
644
+ Example:
645
+
646
+ .. code-block:: python
647
+
648
+ from google.cloud import bigquery
649
+ client = bigquery.Client()
650
+ dataset = bigquery.Dataset('my_project.my_dataset')
651
+ dataset = client.create_dataset(dataset)
652
+
653
+ Args:
654
+ dataset (Union[ \
655
+ google.cloud.bigquery.dataset.Dataset, \
656
+ google.cloud.bigquery.dataset.DatasetReference, \
657
+ google.cloud.bigquery.dataset.DatasetListItem, \
658
+ str, \
659
+ ]):
660
+ A :class:`~google.cloud.bigquery.dataset.Dataset` to create.
661
+ If ``dataset`` is a reference, an empty dataset is created
662
+ with the specified ID and client's default location.
663
+ exists_ok (Optional[bool]):
664
+ Defaults to ``False``. If ``True``, ignore "already exists"
665
+ errors when creating the dataset.
666
+ retry (Optional[google.api_core.retry.Retry]):
667
+ How to retry the RPC.
668
+ timeout (Optional[float]):
669
+ The number of seconds to wait for the underlying HTTP transport
670
+ before using ``retry``.
671
+
672
+ Returns:
673
+ google.cloud.bigquery.dataset.Dataset:
674
+ A new ``Dataset`` returned from the API.
675
+
676
+ Raises:
677
+ google.cloud.exceptions.Conflict:
678
+ If the dataset already exists.
679
+ """
680
+ dataset = self._dataset_from_arg(dataset)
681
+ if isinstance(dataset, DatasetReference):
682
+ dataset = Dataset(dataset)
683
+
684
+ path = "/projects/%s/datasets" % (dataset.project,)
685
+
686
+ data = dataset.to_api_repr()
687
+ if data.get("location") is None and self.location is not None:
688
+ data["location"] = self.location
689
+
690
+ try:
691
+ span_attributes = {"path": path}
692
+
693
+ api_response = self._call_api(
694
+ retry,
695
+ span_name="BigQuery.createDataset",
696
+ span_attributes=span_attributes,
697
+ method="POST",
698
+ path=path,
699
+ data=data,
700
+ timeout=timeout,
701
+ )
702
+ return Dataset.from_api_repr(api_response)
703
+ except core_exceptions.Conflict:
704
+ if not exists_ok:
705
+ raise
706
+ return self.get_dataset(dataset.reference, retry=retry)
707
+
708
+ def create_routine(
709
+ self,
710
+ routine: Routine,
711
+ exists_ok: bool = False,
712
+ retry: retries.Retry = DEFAULT_RETRY,
713
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
714
+ ) -> Routine:
715
+ """[Beta] Create a routine via a POST request.
716
+
717
+ See
718
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/routines/insert
719
+
720
+ Args:
721
+ routine (google.cloud.bigquery.routine.Routine):
722
+ A :class:`~google.cloud.bigquery.routine.Routine` to create.
723
+ The dataset that the routine belongs to must already exist.
724
+ exists_ok (Optional[bool]):
725
+ Defaults to ``False``. If ``True``, ignore "already exists"
726
+ errors when creating the routine.
727
+ retry (Optional[google.api_core.retry.Retry]):
728
+ How to retry the RPC.
729
+ timeout (Optional[float]):
730
+ The number of seconds to wait for the underlying HTTP transport
731
+ before using ``retry``.
732
+
733
+ Returns:
734
+ google.cloud.bigquery.routine.Routine:
735
+ A new ``Routine`` returned from the service.
736
+
737
+ Raises:
738
+ google.cloud.exceptions.Conflict:
739
+ If the routine already exists.
740
+ """
741
+ reference = routine.reference
742
+ path = "/projects/{}/datasets/{}/routines".format(
743
+ reference.project, reference.dataset_id
744
+ )
745
+ resource = routine.to_api_repr()
746
+ try:
747
+ span_attributes = {"path": path}
748
+ api_response = self._call_api(
749
+ retry,
750
+ span_name="BigQuery.createRoutine",
751
+ span_attributes=span_attributes,
752
+ method="POST",
753
+ path=path,
754
+ data=resource,
755
+ timeout=timeout,
756
+ )
757
+ return Routine.from_api_repr(api_response)
758
+ except core_exceptions.Conflict:
759
+ if not exists_ok:
760
+ raise
761
+ return self.get_routine(routine.reference, retry=retry)
762
+
763
+ def create_table(
764
+ self,
765
+ table: Union[str, Table, TableReference, TableListItem],
766
+ exists_ok: bool = False,
767
+ retry: retries.Retry = DEFAULT_RETRY,
768
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
769
+ ) -> Table:
770
+ """API call: create a table via a PUT request
771
+
772
+ See
773
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/tables/insert
774
+
775
+ Args:
776
+ table (Union[ \
777
+ google.cloud.bigquery.table.Table, \
778
+ google.cloud.bigquery.table.TableReference, \
779
+ google.cloud.bigquery.table.TableListItem, \
780
+ str, \
781
+ ]):
782
+ A :class:`~google.cloud.bigquery.table.Table` to create.
783
+ If ``table`` is a reference, an empty table is created
784
+ with the specified ID. The dataset that the table belongs to
785
+ must already exist.
786
+ exists_ok (Optional[bool]):
787
+ Defaults to ``False``. If ``True``, ignore "already exists"
788
+ errors when creating the table.
789
+ retry (Optional[google.api_core.retry.Retry]):
790
+ How to retry the RPC.
791
+ timeout (Optional[float]):
792
+ The number of seconds to wait for the underlying HTTP transport
793
+ before using ``retry``.
794
+
795
+ Returns:
796
+ google.cloud.bigquery.table.Table:
797
+ A new ``Table`` returned from the service.
798
+
799
+ Raises:
800
+ google.cloud.exceptions.Conflict:
801
+ If the table already exists.
802
+ """
803
+ table = _table_arg_to_table(table, default_project=self.project)
804
+ dataset_id = table.dataset_id
805
+ path = "/projects/%s/datasets/%s/tables" % (table.project, dataset_id)
806
+ data = table.to_api_repr()
807
+ try:
808
+ span_attributes = {"path": path, "dataset_id": dataset_id}
809
+ api_response = self._call_api(
810
+ retry,
811
+ span_name="BigQuery.createTable",
812
+ span_attributes=span_attributes,
813
+ method="POST",
814
+ path=path,
815
+ data=data,
816
+ timeout=timeout,
817
+ )
818
+ return Table.from_api_repr(api_response)
819
+ except core_exceptions.Conflict:
820
+ if not exists_ok:
821
+ raise
822
+ return self.get_table(table.reference, retry=retry)
823
+
824
+ def _call_api(
825
+ self,
826
+ retry,
827
+ span_name=None,
828
+ span_attributes=None,
829
+ job_ref=None,
830
+ headers: Optional[Dict[str, str]] = None,
831
+ **kwargs,
832
+ ):
833
+ kwargs = _add_server_timeout_header(headers, kwargs)
834
+ call = functools.partial(self._connection.api_request, **kwargs)
835
+
836
+ if retry:
837
+ call = retry(call)
838
+
839
+ if span_name is not None:
840
+ with create_span(
841
+ name=span_name, attributes=span_attributes, client=self, job_ref=job_ref
842
+ ):
843
+ return call()
844
+
845
+ return call()
846
+
847
+ def get_dataset(
848
+ self,
849
+ dataset_ref: Union[DatasetReference, str],
850
+ retry: retries.Retry = DEFAULT_RETRY,
851
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
852
+ ) -> Dataset:
853
+ """Fetch the dataset referenced by ``dataset_ref``
854
+
855
+ Args:
856
+ dataset_ref (Union[ \
857
+ google.cloud.bigquery.dataset.DatasetReference, \
858
+ str, \
859
+ ]):
860
+ A reference to the dataset to fetch from the BigQuery API.
861
+ If a string is passed in, this method attempts to create a
862
+ dataset reference from a string using
863
+ :func:`~google.cloud.bigquery.dataset.DatasetReference.from_string`.
864
+ retry (Optional[google.api_core.retry.Retry]):
865
+ How to retry the RPC.
866
+ timeout (Optional[float]):
867
+ The number of seconds to wait for the underlying HTTP transport
868
+ before using ``retry``.
869
+
870
+ Returns:
871
+ google.cloud.bigquery.dataset.Dataset:
872
+ A ``Dataset`` instance.
873
+ """
874
+ if isinstance(dataset_ref, str):
875
+ dataset_ref = DatasetReference.from_string(
876
+ dataset_ref, default_project=self.project
877
+ )
878
+ path = dataset_ref.path
879
+ span_attributes = {"path": path}
880
+ api_response = self._call_api(
881
+ retry,
882
+ span_name="BigQuery.getDataset",
883
+ span_attributes=span_attributes,
884
+ method="GET",
885
+ path=path,
886
+ timeout=timeout,
887
+ )
888
+ return Dataset.from_api_repr(api_response)
889
+
890
+ def get_iam_policy(
891
+ self,
892
+ table: Union[Table, TableReference, TableListItem, str],
893
+ requested_policy_version: int = 1,
894
+ retry: retries.Retry = DEFAULT_RETRY,
895
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
896
+ ) -> Policy:
897
+ """Return the access control policy for a table resource.
898
+
899
+ Args:
900
+ table (Union[ \
901
+ google.cloud.bigquery.table.Table, \
902
+ google.cloud.bigquery.table.TableReference, \
903
+ google.cloud.bigquery.table.TableListItem, \
904
+ str, \
905
+ ]):
906
+ The table to get the access control policy for.
907
+ If a string is passed in, this method attempts to create a
908
+ table reference from a string using
909
+ :func:`~google.cloud.bigquery.table.TableReference.from_string`.
910
+ requested_policy_version (int):
911
+ Optional. The maximum policy version that will be used to format the policy.
912
+
913
+ Only version ``1`` is currently supported.
914
+
915
+ See: https://cloud.google.com/bigquery/docs/reference/rest/v2/GetPolicyOptions
916
+ retry (Optional[google.api_core.retry.Retry]):
917
+ How to retry the RPC.
918
+ timeout (Optional[float]):
919
+ The number of seconds to wait for the underlying HTTP transport
920
+ before using ``retry``.
921
+
922
+ Returns:
923
+ google.api_core.iam.Policy:
924
+ The access control policy.
925
+ """
926
+ table = _table_arg_to_table_ref(table, default_project=self.project)
927
+
928
+ if requested_policy_version != 1:
929
+ raise ValueError("only IAM policy version 1 is supported")
930
+
931
+ body = {"options": {"requestedPolicyVersion": 1}}
932
+
933
+ path = "{}:getIamPolicy".format(table.path)
934
+ span_attributes = {"path": path}
935
+ response = self._call_api(
936
+ retry,
937
+ span_name="BigQuery.getIamPolicy",
938
+ span_attributes=span_attributes,
939
+ method="POST",
940
+ path=path,
941
+ data=body,
942
+ timeout=timeout,
943
+ )
944
+
945
+ return Policy.from_api_repr(response)
946
+
947
+ def set_iam_policy(
948
+ self,
949
+ table: Union[Table, TableReference, TableListItem, str],
950
+ policy: Policy,
951
+ updateMask: Optional[str] = None,
952
+ retry: retries.Retry = DEFAULT_RETRY,
953
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
954
+ *,
955
+ fields: Sequence[str] = (),
956
+ ) -> Policy:
957
+ """Return the access control policy for a table resource.
958
+
959
+ Args:
960
+ table (Union[ \
961
+ google.cloud.bigquery.table.Table, \
962
+ google.cloud.bigquery.table.TableReference, \
963
+ google.cloud.bigquery.table.TableListItem, \
964
+ str, \
965
+ ]):
966
+ The table to get the access control policy for.
967
+ If a string is passed in, this method attempts to create a
968
+ table reference from a string using
969
+ :func:`~google.cloud.bigquery.table.TableReference.from_string`.
970
+ policy (google.api_core.iam.Policy):
971
+ The access control policy to set.
972
+ updateMask (Optional[str]):
973
+ Mask as defined by
974
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/tables/setIamPolicy#body.request_body.FIELDS.update_mask
975
+
976
+ Incompatible with ``fields``.
977
+ retry (Optional[google.api_core.retry.Retry]):
978
+ How to retry the RPC.
979
+ timeout (Optional[float]):
980
+ The number of seconds to wait for the underlying HTTP transport
981
+ before using ``retry``.
982
+ fields (Sequence[str]):
983
+ Which properties to set on the policy. See:
984
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/tables/setIamPolicy#body.request_body.FIELDS.update_mask
985
+
986
+ Incompatible with ``updateMask``.
987
+
988
+ Returns:
989
+ google.api_core.iam.Policy:
990
+ The updated access control policy.
991
+ """
992
+ if updateMask is not None and not fields:
993
+ update_mask = updateMask
994
+ elif updateMask is not None and fields:
995
+ raise ValueError("Cannot set both fields and updateMask")
996
+ elif fields:
997
+ update_mask = ",".join(fields)
998
+ else:
999
+ update_mask = None
1000
+
1001
+ table = _table_arg_to_table_ref(table, default_project=self.project)
1002
+
1003
+ if not isinstance(policy, (Policy)):
1004
+ raise TypeError("policy must be a Policy")
1005
+
1006
+ body = {"policy": policy.to_api_repr()}
1007
+
1008
+ if update_mask is not None:
1009
+ body["updateMask"] = update_mask
1010
+
1011
+ path = "{}:setIamPolicy".format(table.path)
1012
+ span_attributes = {"path": path}
1013
+
1014
+ response = self._call_api(
1015
+ retry,
1016
+ span_name="BigQuery.setIamPolicy",
1017
+ span_attributes=span_attributes,
1018
+ method="POST",
1019
+ path=path,
1020
+ data=body,
1021
+ timeout=timeout,
1022
+ )
1023
+
1024
+ return Policy.from_api_repr(response)
1025
+
1026
+ def test_iam_permissions(
1027
+ self,
1028
+ table: Union[Table, TableReference, TableListItem, str],
1029
+ permissions: Sequence[str],
1030
+ retry: retries.Retry = DEFAULT_RETRY,
1031
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1032
+ ) -> Dict[str, Any]:
1033
+ table = _table_arg_to_table_ref(table, default_project=self.project)
1034
+
1035
+ body = {"permissions": permissions}
1036
+
1037
+ path = "{}:testIamPermissions".format(table.path)
1038
+ span_attributes = {"path": path}
1039
+ response = self._call_api(
1040
+ retry,
1041
+ span_name="BigQuery.testIamPermissions",
1042
+ span_attributes=span_attributes,
1043
+ method="POST",
1044
+ path=path,
1045
+ data=body,
1046
+ timeout=timeout,
1047
+ )
1048
+
1049
+ return response
1050
+
1051
+ def get_model(
1052
+ self,
1053
+ model_ref: Union[ModelReference, str],
1054
+ retry: retries.Retry = DEFAULT_RETRY,
1055
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1056
+ ) -> Model:
1057
+ """[Beta] Fetch the model referenced by ``model_ref``.
1058
+
1059
+ Args:
1060
+ model_ref (Union[ \
1061
+ google.cloud.bigquery.model.ModelReference, \
1062
+ str, \
1063
+ ]):
1064
+ A reference to the model to fetch from the BigQuery API.
1065
+ If a string is passed in, this method attempts to create a
1066
+ model reference from a string using
1067
+ :func:`google.cloud.bigquery.model.ModelReference.from_string`.
1068
+ retry (Optional[google.api_core.retry.Retry]):
1069
+ How to retry the RPC.
1070
+ timeout (Optional[float]):
1071
+ The number of seconds to wait for the underlying HTTP transport
1072
+ before using ``retry``.
1073
+
1074
+ Returns:
1075
+ google.cloud.bigquery.model.Model: A ``Model`` instance.
1076
+ """
1077
+ if isinstance(model_ref, str):
1078
+ model_ref = ModelReference.from_string(
1079
+ model_ref, default_project=self.project
1080
+ )
1081
+ path = model_ref.path
1082
+ span_attributes = {"path": path}
1083
+
1084
+ api_response = self._call_api(
1085
+ retry,
1086
+ span_name="BigQuery.getModel",
1087
+ span_attributes=span_attributes,
1088
+ method="GET",
1089
+ path=path,
1090
+ timeout=timeout,
1091
+ )
1092
+ return Model.from_api_repr(api_response)
1093
+
1094
+ def get_routine(
1095
+ self,
1096
+ routine_ref: Union[Routine, RoutineReference, str],
1097
+ retry: retries.Retry = DEFAULT_RETRY,
1098
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1099
+ ) -> Routine:
1100
+ """[Beta] Get the routine referenced by ``routine_ref``.
1101
+
1102
+ Args:
1103
+ routine_ref (Union[ \
1104
+ google.cloud.bigquery.routine.Routine, \
1105
+ google.cloud.bigquery.routine.RoutineReference, \
1106
+ str, \
1107
+ ]):
1108
+ A reference to the routine to fetch from the BigQuery API. If
1109
+ a string is passed in, this method attempts to create a
1110
+ reference from a string using
1111
+ :func:`google.cloud.bigquery.routine.RoutineReference.from_string`.
1112
+ retry (Optional[google.api_core.retry.Retry]):
1113
+ How to retry the API call.
1114
+ timeout (Optional[float]):
1115
+ The number of seconds to wait for the underlying HTTP transport
1116
+ before using ``retry``.
1117
+
1118
+ Returns:
1119
+ google.cloud.bigquery.routine.Routine:
1120
+ A ``Routine`` instance.
1121
+ """
1122
+ if isinstance(routine_ref, str):
1123
+ routine_ref = RoutineReference.from_string(
1124
+ routine_ref, default_project=self.project
1125
+ )
1126
+ path = routine_ref.path
1127
+ span_attributes = {"path": path}
1128
+ api_response = self._call_api(
1129
+ retry,
1130
+ span_name="BigQuery.getRoutine",
1131
+ span_attributes=span_attributes,
1132
+ method="GET",
1133
+ path=path,
1134
+ timeout=timeout,
1135
+ )
1136
+ return Routine.from_api_repr(api_response)
1137
+
1138
+ def get_table(
1139
+ self,
1140
+ table: Union[Table, TableReference, TableListItem, str],
1141
+ retry: retries.Retry = DEFAULT_RETRY,
1142
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1143
+ ) -> Table:
1144
+ """Fetch the table referenced by ``table``.
1145
+
1146
+ Args:
1147
+ table (Union[ \
1148
+ google.cloud.bigquery.table.Table, \
1149
+ google.cloud.bigquery.table.TableReference, \
1150
+ google.cloud.bigquery.table.TableListItem, \
1151
+ str, \
1152
+ ]):
1153
+ A reference to the table to fetch from the BigQuery API.
1154
+ If a string is passed in, this method attempts to create a
1155
+ table reference from a string using
1156
+ :func:`google.cloud.bigquery.table.TableReference.from_string`.
1157
+ retry (Optional[google.api_core.retry.Retry]):
1158
+ How to retry the RPC.
1159
+ timeout (Optional[float]):
1160
+ The number of seconds to wait for the underlying HTTP transport
1161
+ before using ``retry``.
1162
+
1163
+ Returns:
1164
+ google.cloud.bigquery.table.Table:
1165
+ A ``Table`` instance.
1166
+ """
1167
+ table_ref = _table_arg_to_table_ref(table, default_project=self.project)
1168
+ path = table_ref.path
1169
+ span_attributes = {"path": path}
1170
+ api_response = self._call_api(
1171
+ retry,
1172
+ span_name="BigQuery.getTable",
1173
+ span_attributes=span_attributes,
1174
+ method="GET",
1175
+ path=path,
1176
+ timeout=timeout,
1177
+ )
1178
+ return Table.from_api_repr(api_response)
1179
+
1180
+ def update_dataset(
1181
+ self,
1182
+ dataset: Dataset,
1183
+ fields: Sequence[str],
1184
+ retry: retries.Retry = DEFAULT_RETRY,
1185
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1186
+ ) -> Dataset:
1187
+ """Change some fields of a dataset.
1188
+
1189
+ Use ``fields`` to specify which fields to update. At least one field
1190
+ must be provided. If a field is listed in ``fields`` and is ``None`` in
1191
+ ``dataset``, it will be deleted.
1192
+
1193
+ For example, to update the default expiration times, specify
1194
+ both properties in the ``fields`` argument:
1195
+
1196
+ .. code-block:: python
1197
+
1198
+ bigquery_client.update_dataset(
1199
+ dataset,
1200
+ [
1201
+ "default_partition_expiration_ms",
1202
+ "default_table_expiration_ms",
1203
+ ]
1204
+ )
1205
+
1206
+ If ``dataset.etag`` is not ``None``, the update will only
1207
+ succeed if the dataset on the server has the same ETag. Thus
1208
+ reading a dataset with ``get_dataset``, changing its fields,
1209
+ and then passing it to ``update_dataset`` will ensure that the changes
1210
+ will only be saved if no modifications to the dataset occurred
1211
+ since the read.
1212
+
1213
+ Args:
1214
+ dataset (google.cloud.bigquery.dataset.Dataset):
1215
+ The dataset to update.
1216
+ fields (Sequence[str]):
1217
+ The properties of ``dataset`` to change. These are strings
1218
+ corresponding to the properties of
1219
+ :class:`~google.cloud.bigquery.dataset.Dataset`.
1220
+ retry (Optional[google.api_core.retry.Retry]):
1221
+ How to retry the RPC.
1222
+ timeout (Optional[float]):
1223
+ The number of seconds to wait for the underlying HTTP transport
1224
+ before using ``retry``.
1225
+
1226
+ Returns:
1227
+ google.cloud.bigquery.dataset.Dataset:
1228
+ The modified ``Dataset`` instance.
1229
+ """
1230
+ partial = dataset._build_resource(fields)
1231
+ if dataset.etag is not None:
1232
+ headers: Optional[Dict[str, str]] = {"If-Match": dataset.etag}
1233
+ else:
1234
+ headers = None
1235
+ path = dataset.path
1236
+ span_attributes = {"path": path, "fields": fields}
1237
+
1238
+ api_response = self._call_api(
1239
+ retry,
1240
+ span_name="BigQuery.updateDataset",
1241
+ span_attributes=span_attributes,
1242
+ method="PATCH",
1243
+ path=path,
1244
+ data=partial,
1245
+ headers=headers,
1246
+ timeout=timeout,
1247
+ )
1248
+ return Dataset.from_api_repr(api_response)
1249
+
1250
+ def update_model(
1251
+ self,
1252
+ model: Model,
1253
+ fields: Sequence[str],
1254
+ retry: retries.Retry = DEFAULT_RETRY,
1255
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1256
+ ) -> Model:
1257
+ """[Beta] Change some fields of a model.
1258
+
1259
+ Use ``fields`` to specify which fields to update. At least one field
1260
+ must be provided. If a field is listed in ``fields`` and is ``None``
1261
+ in ``model``, the field value will be deleted.
1262
+
1263
+ For example, to update the descriptive properties of the model,
1264
+ specify them in the ``fields`` argument:
1265
+
1266
+ .. code-block:: python
1267
+
1268
+ bigquery_client.update_model(
1269
+ model, ["description", "friendly_name"]
1270
+ )
1271
+
1272
+ If ``model.etag`` is not ``None``, the update will only succeed if
1273
+ the model on the server has the same ETag. Thus reading a model with
1274
+ ``get_model``, changing its fields, and then passing it to
1275
+ ``update_model`` will ensure that the changes will only be saved if
1276
+ no modifications to the model occurred since the read.
1277
+
1278
+ Args:
1279
+ model (google.cloud.bigquery.model.Model): The model to update.
1280
+ fields (Sequence[str]):
1281
+ The properties of ``model`` to change. These are strings
1282
+ corresponding to the properties of
1283
+ :class:`~google.cloud.bigquery.model.Model`.
1284
+ retry (Optional[google.api_core.retry.Retry]):
1285
+ A description of how to retry the API call.
1286
+ timeout (Optional[float]):
1287
+ The number of seconds to wait for the underlying HTTP transport
1288
+ before using ``retry``.
1289
+
1290
+ Returns:
1291
+ google.cloud.bigquery.model.Model:
1292
+ The model resource returned from the API call.
1293
+ """
1294
+ partial = model._build_resource(fields)
1295
+ if model.etag:
1296
+ headers: Optional[Dict[str, str]] = {"If-Match": model.etag}
1297
+ else:
1298
+ headers = None
1299
+ path = model.path
1300
+ span_attributes = {"path": path, "fields": fields}
1301
+
1302
+ api_response = self._call_api(
1303
+ retry,
1304
+ span_name="BigQuery.updateModel",
1305
+ span_attributes=span_attributes,
1306
+ method="PATCH",
1307
+ path=path,
1308
+ data=partial,
1309
+ headers=headers,
1310
+ timeout=timeout,
1311
+ )
1312
+ return Model.from_api_repr(api_response)
1313
+
1314
+ def update_routine(
1315
+ self,
1316
+ routine: Routine,
1317
+ fields: Sequence[str],
1318
+ retry: retries.Retry = DEFAULT_RETRY,
1319
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1320
+ ) -> Routine:
1321
+ """[Beta] Change some fields of a routine.
1322
+
1323
+ Use ``fields`` to specify which fields to update. At least one field
1324
+ must be provided. If a field is listed in ``fields`` and is ``None``
1325
+ in ``routine``, the field value will be deleted.
1326
+
1327
+ For example, to update the description property of the routine,
1328
+ specify it in the ``fields`` argument:
1329
+
1330
+ .. code-block:: python
1331
+
1332
+ bigquery_client.update_routine(
1333
+ routine, ["description"]
1334
+ )
1335
+
1336
+ .. warning::
1337
+ During beta, partial updates are not supported. You must provide
1338
+ all fields in the resource.
1339
+
1340
+ If :attr:`~google.cloud.bigquery.routine.Routine.etag` is not
1341
+ ``None``, the update will only succeed if the resource on the server
1342
+ has the same ETag. Thus reading a routine with
1343
+ :func:`~google.cloud.bigquery.client.Client.get_routine`, changing
1344
+ its fields, and then passing it to this method will ensure that the
1345
+ changes will only be saved if no modifications to the resource
1346
+ occurred since the read.
1347
+
1348
+ Args:
1349
+ routine (google.cloud.bigquery.routine.Routine):
1350
+ The routine to update.
1351
+ fields (Sequence[str]):
1352
+ The fields of ``routine`` to change, spelled as the
1353
+ :class:`~google.cloud.bigquery.routine.Routine` properties.
1354
+ retry (Optional[google.api_core.retry.Retry]):
1355
+ A description of how to retry the API call.
1356
+ timeout (Optional[float]):
1357
+ The number of seconds to wait for the underlying HTTP transport
1358
+ before using ``retry``.
1359
+
1360
+ Returns:
1361
+ google.cloud.bigquery.routine.Routine:
1362
+ The routine resource returned from the API call.
1363
+ """
1364
+ partial = routine._build_resource(fields)
1365
+ if routine.etag:
1366
+ headers: Optional[Dict[str, str]] = {"If-Match": routine.etag}
1367
+ else:
1368
+ headers = None
1369
+
1370
+ # TODO: remove when routines update supports partial requests.
1371
+ partial["routineReference"] = routine.reference.to_api_repr()
1372
+
1373
+ path = routine.path
1374
+ span_attributes = {"path": path, "fields": fields}
1375
+
1376
+ api_response = self._call_api(
1377
+ retry,
1378
+ span_name="BigQuery.updateRoutine",
1379
+ span_attributes=span_attributes,
1380
+ method="PUT",
1381
+ path=path,
1382
+ data=partial,
1383
+ headers=headers,
1384
+ timeout=timeout,
1385
+ )
1386
+ return Routine.from_api_repr(api_response)
1387
+
1388
+ def update_table(
1389
+ self,
1390
+ table: Table,
1391
+ fields: Sequence[str],
1392
+ retry: retries.Retry = DEFAULT_RETRY,
1393
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1394
+ ) -> Table:
1395
+ """Change some fields of a table.
1396
+
1397
+ Use ``fields`` to specify which fields to update. At least one field
1398
+ must be provided. If a field is listed in ``fields`` and is ``None``
1399
+ in ``table``, the field value will be deleted.
1400
+
1401
+ For example, to update the descriptive properties of the table,
1402
+ specify them in the ``fields`` argument:
1403
+
1404
+ .. code-block:: python
1405
+
1406
+ bigquery_client.update_table(
1407
+ table,
1408
+ ["description", "friendly_name"]
1409
+ )
1410
+
1411
+ If ``table.etag`` is not ``None``, the update will only succeed if
1412
+ the table on the server has the same ETag. Thus reading a table with
1413
+ ``get_table``, changing its fields, and then passing it to
1414
+ ``update_table`` will ensure that the changes will only be saved if
1415
+ no modifications to the table occurred since the read.
1416
+
1417
+ Args:
1418
+ table (google.cloud.bigquery.table.Table): The table to update.
1419
+ fields (Sequence[str]):
1420
+ The fields of ``table`` to change, spelled as the
1421
+ :class:`~google.cloud.bigquery.table.Table` properties.
1422
+ retry (Optional[google.api_core.retry.Retry]):
1423
+ A description of how to retry the API call.
1424
+ timeout (Optional[float]):
1425
+ The number of seconds to wait for the underlying HTTP transport
1426
+ before using ``retry``.
1427
+
1428
+ Returns:
1429
+ google.cloud.bigquery.table.Table:
1430
+ The table resource returned from the API call.
1431
+ """
1432
+ partial = table._build_resource(fields)
1433
+ if table.etag is not None:
1434
+ headers: Optional[Dict[str, str]] = {"If-Match": table.etag}
1435
+ else:
1436
+ headers = None
1437
+
1438
+ path = table.path
1439
+ span_attributes = {"path": path, "fields": fields}
1440
+
1441
+ api_response = self._call_api(
1442
+ retry,
1443
+ span_name="BigQuery.updateTable",
1444
+ span_attributes=span_attributes,
1445
+ method="PATCH",
1446
+ path=path,
1447
+ data=partial,
1448
+ headers=headers,
1449
+ timeout=timeout,
1450
+ )
1451
+ return Table.from_api_repr(api_response)
1452
+
1453
+ def list_models(
1454
+ self,
1455
+ dataset: Union[Dataset, DatasetReference, DatasetListItem, str],
1456
+ max_results: Optional[int] = None,
1457
+ page_token: Optional[str] = None,
1458
+ retry: retries.Retry = DEFAULT_RETRY,
1459
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1460
+ page_size: Optional[int] = None,
1461
+ ) -> page_iterator.Iterator:
1462
+ """[Beta] List models in the dataset.
1463
+
1464
+ See
1465
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/models/list
1466
+
1467
+ Args:
1468
+ dataset (Union[ \
1469
+ google.cloud.bigquery.dataset.Dataset, \
1470
+ google.cloud.bigquery.dataset.DatasetReference, \
1471
+ google.cloud.bigquery.dataset.DatasetListItem, \
1472
+ str, \
1473
+ ]):
1474
+ A reference to the dataset whose models to list from the
1475
+ BigQuery API. If a string is passed in, this method attempts
1476
+ to create a dataset reference from a string using
1477
+ :func:`google.cloud.bigquery.dataset.DatasetReference.from_string`.
1478
+ max_results (Optional[int]):
1479
+ Maximum number of models to return. Defaults to a
1480
+ value set by the API.
1481
+ page_token (Optional[str]):
1482
+ Token representing a cursor into the models. If not passed,
1483
+ the API will return the first page of models. The token marks
1484
+ the beginning of the iterator to be returned and the value of
1485
+ the ``page_token`` can be accessed at ``next_page_token`` of the
1486
+ :class:`~google.api_core.page_iterator.HTTPIterator`.
1487
+ retry (Optional[google.api_core.retry.Retry]):
1488
+ How to retry the RPC.
1489
+ timeout (Optional[float]):
1490
+ The number of seconds to wait for the underlying HTTP transport
1491
+ before using ``retry``.
1492
+ page_size (Optional[int]):
1493
+ Maximum number of models to return per page.
1494
+ Defaults to a value set by the API.
1495
+
1496
+ Returns:
1497
+ google.api_core.page_iterator.Iterator:
1498
+ Iterator of
1499
+ :class:`~google.cloud.bigquery.model.Model` contained
1500
+ within the requested dataset.
1501
+ """
1502
+ dataset = self._dataset_from_arg(dataset)
1503
+
1504
+ path = "%s/models" % dataset.path
1505
+ span_attributes = {"path": path}
1506
+
1507
+ def api_request(*args, **kwargs):
1508
+ return self._call_api(
1509
+ retry,
1510
+ span_name="BigQuery.listModels",
1511
+ span_attributes=span_attributes,
1512
+ *args,
1513
+ timeout=timeout,
1514
+ **kwargs,
1515
+ )
1516
+
1517
+ result = page_iterator.HTTPIterator(
1518
+ client=self,
1519
+ api_request=api_request,
1520
+ path=path,
1521
+ item_to_value=_item_to_model,
1522
+ items_key="models",
1523
+ page_token=page_token,
1524
+ max_results=max_results,
1525
+ page_size=page_size,
1526
+ )
1527
+ result.dataset = dataset # type: ignore
1528
+ return result
1529
+
1530
+ def list_routines(
1531
+ self,
1532
+ dataset: Union[Dataset, DatasetReference, DatasetListItem, str],
1533
+ max_results: Optional[int] = None,
1534
+ page_token: Optional[str] = None,
1535
+ retry: retries.Retry = DEFAULT_RETRY,
1536
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1537
+ page_size: Optional[int] = None,
1538
+ ) -> page_iterator.Iterator:
1539
+ """[Beta] List routines in the dataset.
1540
+
1541
+ See
1542
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/routines/list
1543
+
1544
+ Args:
1545
+ dataset (Union[ \
1546
+ google.cloud.bigquery.dataset.Dataset, \
1547
+ google.cloud.bigquery.dataset.DatasetReference, \
1548
+ google.cloud.bigquery.dataset.DatasetListItem, \
1549
+ str, \
1550
+ ]):
1551
+ A reference to the dataset whose routines to list from the
1552
+ BigQuery API. If a string is passed in, this method attempts
1553
+ to create a dataset reference from a string using
1554
+ :func:`google.cloud.bigquery.dataset.DatasetReference.from_string`.
1555
+ max_results (Optional[int]):
1556
+ Maximum number of routines to return. Defaults
1557
+ to a value set by the API.
1558
+ page_token (Optional[str]):
1559
+ Token representing a cursor into the routines. If not passed,
1560
+ the API will return the first page of routines. The token marks
1561
+ the beginning of the iterator to be returned and the value of the
1562
+ ``page_token`` can be accessed at ``next_page_token`` of the
1563
+ :class:`~google.api_core.page_iterator.HTTPIterator`.
1564
+ retry (Optional[google.api_core.retry.Retry]):
1565
+ How to retry the RPC.
1566
+ timeout (Optional[float]):
1567
+ The number of seconds to wait for the underlying HTTP transport
1568
+ before using ``retry``.
1569
+ page_size (Optional[int]):
1570
+ Maximum number of routines to return per page.
1571
+ Defaults to a value set by the API.
1572
+
1573
+ Returns:
1574
+ google.api_core.page_iterator.Iterator:
1575
+ Iterator of all
1576
+ :class:`~google.cloud.bigquery.routine.Routine`s contained
1577
+ within the requested dataset, limited by ``max_results``.
1578
+ """
1579
+ dataset = self._dataset_from_arg(dataset)
1580
+ path = "{}/routines".format(dataset.path)
1581
+
1582
+ span_attributes = {"path": path}
1583
+
1584
+ def api_request(*args, **kwargs):
1585
+ return self._call_api(
1586
+ retry,
1587
+ span_name="BigQuery.listRoutines",
1588
+ span_attributes=span_attributes,
1589
+ *args,
1590
+ timeout=timeout,
1591
+ **kwargs,
1592
+ )
1593
+
1594
+ result = page_iterator.HTTPIterator(
1595
+ client=self,
1596
+ api_request=api_request,
1597
+ path=path,
1598
+ item_to_value=_item_to_routine,
1599
+ items_key="routines",
1600
+ page_token=page_token,
1601
+ max_results=max_results,
1602
+ page_size=page_size,
1603
+ )
1604
+ result.dataset = dataset # type: ignore
1605
+ return result
1606
+
1607
+ def list_tables(
1608
+ self,
1609
+ dataset: Union[Dataset, DatasetReference, DatasetListItem, str],
1610
+ max_results: Optional[int] = None,
1611
+ page_token: Optional[str] = None,
1612
+ retry: retries.Retry = DEFAULT_RETRY,
1613
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1614
+ page_size: Optional[int] = None,
1615
+ ) -> page_iterator.Iterator:
1616
+ """List tables in the dataset.
1617
+
1618
+ See
1619
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/tables/list
1620
+
1621
+ Args:
1622
+ dataset (Union[ \
1623
+ google.cloud.bigquery.dataset.Dataset, \
1624
+ google.cloud.bigquery.dataset.DatasetReference, \
1625
+ google.cloud.bigquery.dataset.DatasetListItem, \
1626
+ str, \
1627
+ ]):
1628
+ A reference to the dataset whose tables to list from the
1629
+ BigQuery API. If a string is passed in, this method attempts
1630
+ to create a dataset reference from a string using
1631
+ :func:`google.cloud.bigquery.dataset.DatasetReference.from_string`.
1632
+ max_results (Optional[int]):
1633
+ Maximum number of tables to return. Defaults
1634
+ to a value set by the API.
1635
+ page_token (Optional[str]):
1636
+ Token representing a cursor into the tables. If not passed,
1637
+ the API will return the first page of tables. The token marks
1638
+ the beginning of the iterator to be returned and the value of
1639
+ the ``page_token`` can be accessed at ``next_page_token`` of the
1640
+ :class:`~google.api_core.page_iterator.HTTPIterator`.
1641
+ retry (Optional[google.api_core.retry.Retry]):
1642
+ How to retry the RPC.
1643
+ timeout (Optional[float]):
1644
+ The number of seconds to wait for the underlying HTTP transport
1645
+ before using ``retry``.
1646
+ page_size (Optional[int]):
1647
+ Maximum number of tables to return per page.
1648
+ Defaults to a value set by the API.
1649
+
1650
+ Returns:
1651
+ google.api_core.page_iterator.Iterator:
1652
+ Iterator of
1653
+ :class:`~google.cloud.bigquery.table.TableListItem` contained
1654
+ within the requested dataset.
1655
+ """
1656
+ dataset = self._dataset_from_arg(dataset)
1657
+ path = "%s/tables" % dataset.path
1658
+ span_attributes = {"path": path}
1659
+
1660
+ def api_request(*args, **kwargs):
1661
+ return self._call_api(
1662
+ retry,
1663
+ span_name="BigQuery.listTables",
1664
+ span_attributes=span_attributes,
1665
+ *args,
1666
+ timeout=timeout,
1667
+ **kwargs,
1668
+ )
1669
+
1670
+ result = page_iterator.HTTPIterator(
1671
+ client=self,
1672
+ api_request=api_request,
1673
+ path=path,
1674
+ item_to_value=_item_to_table,
1675
+ items_key="tables",
1676
+ page_token=page_token,
1677
+ max_results=max_results,
1678
+ page_size=page_size,
1679
+ )
1680
+ result.dataset = dataset # type: ignore
1681
+ return result
1682
+
1683
+ def delete_dataset(
1684
+ self,
1685
+ dataset: Union[Dataset, DatasetReference, DatasetListItem, str],
1686
+ delete_contents: bool = False,
1687
+ retry: retries.Retry = DEFAULT_RETRY,
1688
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1689
+ not_found_ok: bool = False,
1690
+ ) -> None:
1691
+ """Delete a dataset.
1692
+
1693
+ See
1694
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/delete
1695
+
1696
+ Args:
1697
+ dataset (Union[ \
1698
+ google.cloud.bigquery.dataset.Dataset, \
1699
+ google.cloud.bigquery.dataset.DatasetReference, \
1700
+ google.cloud.bigquery.dataset.DatasetListItem, \
1701
+ str, \
1702
+ ]):
1703
+ A reference to the dataset to delete. If a string is passed
1704
+ in, this method attempts to create a dataset reference from a
1705
+ string using
1706
+ :func:`google.cloud.bigquery.dataset.DatasetReference.from_string`.
1707
+ delete_contents (Optional[bool]):
1708
+ If True, delete all the tables in the dataset. If False and
1709
+ the dataset contains tables, the request will fail.
1710
+ Default is False.
1711
+ retry (Optional[google.api_core.retry.Retry]):
1712
+ How to retry the RPC.
1713
+ timeout (Optional[float]):
1714
+ The number of seconds to wait for the underlying HTTP transport
1715
+ before using ``retry``.
1716
+ not_found_ok (Optional[bool]):
1717
+ Defaults to ``False``. If ``True``, ignore "not found" errors
1718
+ when deleting the dataset.
1719
+ """
1720
+ dataset = self._dataset_from_arg(dataset)
1721
+ params = {}
1722
+ path = dataset.path
1723
+ if delete_contents:
1724
+ params["deleteContents"] = "true"
1725
+ span_attributes = {"path": path, "deleteContents": delete_contents}
1726
+ else:
1727
+ span_attributes = {"path": path}
1728
+
1729
+ try:
1730
+ self._call_api(
1731
+ retry,
1732
+ span_name="BigQuery.deleteDataset",
1733
+ span_attributes=span_attributes,
1734
+ method="DELETE",
1735
+ path=path,
1736
+ query_params=params,
1737
+ timeout=timeout,
1738
+ )
1739
+ except core_exceptions.NotFound:
1740
+ if not not_found_ok:
1741
+ raise
1742
+
1743
+ def delete_model(
1744
+ self,
1745
+ model: Union[Model, ModelReference, str],
1746
+ retry: retries.Retry = DEFAULT_RETRY,
1747
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1748
+ not_found_ok: bool = False,
1749
+ ) -> None:
1750
+ """[Beta] Delete a model
1751
+
1752
+ See
1753
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/models/delete
1754
+
1755
+ Args:
1756
+ model (Union[ \
1757
+ google.cloud.bigquery.model.Model, \
1758
+ google.cloud.bigquery.model.ModelReference, \
1759
+ str, \
1760
+ ]):
1761
+ A reference to the model to delete. If a string is passed in,
1762
+ this method attempts to create a model reference from a
1763
+ string using
1764
+ :func:`google.cloud.bigquery.model.ModelReference.from_string`.
1765
+ retry (Optional[google.api_core.retry.Retry]):
1766
+ How to retry the RPC.
1767
+ timeout (Optional[float]):
1768
+ The number of seconds to wait for the underlying HTTP transport
1769
+ before using ``retry``.
1770
+ not_found_ok (Optional[bool]):
1771
+ Defaults to ``False``. If ``True``, ignore "not found" errors
1772
+ when deleting the model.
1773
+ """
1774
+ if isinstance(model, str):
1775
+ model = ModelReference.from_string(model, default_project=self.project)
1776
+
1777
+ if not isinstance(model, (Model, ModelReference)):
1778
+ raise TypeError("model must be a Model or a ModelReference")
1779
+
1780
+ path = model.path
1781
+ try:
1782
+ span_attributes = {"path": path}
1783
+ self._call_api(
1784
+ retry,
1785
+ span_name="BigQuery.deleteModel",
1786
+ span_attributes=span_attributes,
1787
+ method="DELETE",
1788
+ path=path,
1789
+ timeout=timeout,
1790
+ )
1791
+ except core_exceptions.NotFound:
1792
+ if not not_found_ok:
1793
+ raise
1794
+
1795
+ def delete_job_metadata(
1796
+ self,
1797
+ job_id: Union[str, LoadJob, CopyJob, ExtractJob, QueryJob],
1798
+ project: Optional[str] = None,
1799
+ location: Optional[str] = None,
1800
+ retry: retries.Retry = DEFAULT_RETRY,
1801
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1802
+ not_found_ok: bool = False,
1803
+ ):
1804
+ """[Beta] Delete job metadata from job history.
1805
+
1806
+ Note: This does not stop a running job. Use
1807
+ :func:`~google.cloud.bigquery.client.Client.cancel_job` instead.
1808
+
1809
+ Args:
1810
+ job_id (Union[ \
1811
+ str, \
1812
+ LoadJob, \
1813
+ CopyJob, \
1814
+ ExtractJob, \
1815
+ QueryJob \
1816
+ ]): Job or job identifier.
1817
+ project (Optional[str]):
1818
+ ID of the project which owns the job (defaults to the client's project).
1819
+ location (Optional[str]):
1820
+ Location where the job was run. Ignored if ``job_id`` is a job
1821
+ object.
1822
+ retry (Optional[google.api_core.retry.Retry]):
1823
+ How to retry the RPC.
1824
+ timeout (Optional[float]):
1825
+ The number of seconds to wait for the underlying HTTP transport
1826
+ before using ``retry``.
1827
+ not_found_ok (Optional[bool]):
1828
+ Defaults to ``False``. If ``True``, ignore "not found" errors
1829
+ when deleting the job.
1830
+ """
1831
+ extra_params = {}
1832
+
1833
+ project, location, job_id = _extract_job_reference(
1834
+ job_id, project=project, location=location
1835
+ )
1836
+
1837
+ if project is None:
1838
+ project = self.project
1839
+
1840
+ if location is None:
1841
+ location = self.location
1842
+
1843
+ # Location is always required for jobs.delete()
1844
+ extra_params["location"] = location
1845
+
1846
+ path = f"/projects/{project}/jobs/{job_id}/delete"
1847
+
1848
+ span_attributes = {"path": path, "job_id": job_id, "location": location}
1849
+
1850
+ try:
1851
+ self._call_api(
1852
+ retry,
1853
+ span_name="BigQuery.deleteJob",
1854
+ span_attributes=span_attributes,
1855
+ method="DELETE",
1856
+ path=path,
1857
+ query_params=extra_params,
1858
+ timeout=timeout,
1859
+ )
1860
+ except google.api_core.exceptions.NotFound:
1861
+ if not not_found_ok:
1862
+ raise
1863
+
1864
+ def delete_routine(
1865
+ self,
1866
+ routine: Union[Routine, RoutineReference, str],
1867
+ retry: retries.Retry = DEFAULT_RETRY,
1868
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1869
+ not_found_ok: bool = False,
1870
+ ) -> None:
1871
+ """[Beta] Delete a routine.
1872
+
1873
+ See
1874
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/routines/delete
1875
+
1876
+ Args:
1877
+ routine (Union[ \
1878
+ google.cloud.bigquery.routine.Routine, \
1879
+ google.cloud.bigquery.routine.RoutineReference, \
1880
+ str, \
1881
+ ]):
1882
+ A reference to the routine to delete. If a string is passed
1883
+ in, this method attempts to create a routine reference from a
1884
+ string using
1885
+ :func:`google.cloud.bigquery.routine.RoutineReference.from_string`.
1886
+ retry (Optional[google.api_core.retry.Retry]):
1887
+ How to retry the RPC.
1888
+ timeout (Optional[float]):
1889
+ The number of seconds to wait for the underlying HTTP transport
1890
+ before using ``retry``.
1891
+ not_found_ok (Optional[bool]):
1892
+ Defaults to ``False``. If ``True``, ignore "not found" errors
1893
+ when deleting the routine.
1894
+ """
1895
+ if isinstance(routine, str):
1896
+ routine = RoutineReference.from_string(
1897
+ routine, default_project=self.project
1898
+ )
1899
+ path = routine.path
1900
+
1901
+ if not isinstance(routine, (Routine, RoutineReference)):
1902
+ raise TypeError("routine must be a Routine or a RoutineReference")
1903
+
1904
+ try:
1905
+ span_attributes = {"path": path}
1906
+ self._call_api(
1907
+ retry,
1908
+ span_name="BigQuery.deleteRoutine",
1909
+ span_attributes=span_attributes,
1910
+ method="DELETE",
1911
+ path=path,
1912
+ timeout=timeout,
1913
+ )
1914
+ except core_exceptions.NotFound:
1915
+ if not not_found_ok:
1916
+ raise
1917
+
1918
+ def delete_table(
1919
+ self,
1920
+ table: Union[Table, TableReference, TableListItem, str],
1921
+ retry: retries.Retry = DEFAULT_RETRY,
1922
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1923
+ not_found_ok: bool = False,
1924
+ ) -> None:
1925
+ """Delete a table
1926
+
1927
+ See
1928
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/tables/delete
1929
+
1930
+ Args:
1931
+ table (Union[ \
1932
+ google.cloud.bigquery.table.Table, \
1933
+ google.cloud.bigquery.table.TableReference, \
1934
+ google.cloud.bigquery.table.TableListItem, \
1935
+ str, \
1936
+ ]):
1937
+ A reference to the table to delete. If a string is passed in,
1938
+ this method attempts to create a table reference from a
1939
+ string using
1940
+ :func:`google.cloud.bigquery.table.TableReference.from_string`.
1941
+ retry (Optional[google.api_core.retry.Retry]):
1942
+ How to retry the RPC.
1943
+ timeout (Optional[float]):
1944
+ The number of seconds to wait for the underlying HTTP transport
1945
+ before using ``retry``.
1946
+ not_found_ok (Optional[bool]):
1947
+ Defaults to ``False``. If ``True``, ignore "not found" errors
1948
+ when deleting the table.
1949
+ """
1950
+ table = _table_arg_to_table_ref(table, default_project=self.project)
1951
+ if not isinstance(table, TableReference):
1952
+ raise TypeError("Unable to get TableReference for table '{}'".format(table))
1953
+
1954
+ try:
1955
+ path = table.path
1956
+ span_attributes = {"path": path}
1957
+ self._call_api(
1958
+ retry,
1959
+ span_name="BigQuery.deleteTable",
1960
+ span_attributes=span_attributes,
1961
+ method="DELETE",
1962
+ path=path,
1963
+ timeout=timeout,
1964
+ )
1965
+ except core_exceptions.NotFound:
1966
+ if not not_found_ok:
1967
+ raise
1968
+
1969
+ def _get_query_results(
1970
+ self,
1971
+ job_id: str,
1972
+ retry: retries.Retry,
1973
+ project: Optional[str] = None,
1974
+ timeout_ms: Optional[int] = None,
1975
+ location: Optional[str] = None,
1976
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
1977
+ page_size: int = 0,
1978
+ ) -> _QueryResults:
1979
+ """Get the query results object for a query job.
1980
+
1981
+ Args:
1982
+ job_id (str): Name of the query job.
1983
+ retry (google.api_core.retry.Retry):
1984
+ How to retry the RPC.
1985
+ project (Optional[str]):
1986
+ Project ID for the query job (defaults to the project of the client).
1987
+ timeout_ms (Optional[int]):
1988
+ Number of milliseconds the the API call should wait for the query
1989
+ to complete before the request times out.
1990
+ location (Optional[str]): Location of the query job.
1991
+ timeout (Optional[float]):
1992
+ The number of seconds to wait for the underlying HTTP transport
1993
+ before using ``retry``. If set, this connection timeout may be
1994
+ increased to a minimum value. This prevents retries on what
1995
+ would otherwise be a successful response.
1996
+ page_size (int):
1997
+ Maximum number of rows in a single response. See maxResults in
1998
+ the jobs.getQueryResults REST API.
1999
+
2000
+ Returns:
2001
+ google.cloud.bigquery.query._QueryResults:
2002
+ A new ``_QueryResults`` instance.
2003
+ """
2004
+
2005
+ extra_params: Dict[str, Any] = {"maxResults": page_size}
2006
+
2007
+ if timeout is not None:
2008
+ if not isinstance(timeout, (int, float)):
2009
+ timeout = _MIN_GET_QUERY_RESULTS_TIMEOUT
2010
+ else:
2011
+ timeout = max(timeout, _MIN_GET_QUERY_RESULTS_TIMEOUT)
2012
+
2013
+ if page_size > 0:
2014
+ extra_params["formatOptions.useInt64Timestamp"] = True
2015
+
2016
+ if project is None:
2017
+ project = self.project
2018
+
2019
+ if timeout_ms is not None:
2020
+ extra_params["timeoutMs"] = timeout_ms
2021
+
2022
+ if location is None:
2023
+ location = self.location
2024
+
2025
+ if location is not None:
2026
+ extra_params["location"] = location
2027
+
2028
+ path = "/projects/{}/queries/{}".format(project, job_id)
2029
+
2030
+ # This call is typically made in a polling loop that checks whether the
2031
+ # job is complete (from QueryJob.done(), called ultimately from
2032
+ # QueryJob.result()). So we don't need to poll here.
2033
+ span_attributes = {"path": path}
2034
+ resource = self._call_api(
2035
+ retry,
2036
+ span_name="BigQuery.getQueryResults",
2037
+ span_attributes=span_attributes,
2038
+ method="GET",
2039
+ path=path,
2040
+ query_params=extra_params,
2041
+ timeout=timeout,
2042
+ )
2043
+ return _QueryResults.from_api_repr(resource)
2044
+
2045
+ def job_from_resource(
2046
+ self, resource: dict
2047
+ ) -> Union[job.CopyJob, job.ExtractJob, job.LoadJob, job.QueryJob, job.UnknownJob]:
2048
+ """Detect correct job type from resource and instantiate.
2049
+
2050
+ Args:
2051
+ resource (Dict): one job resource from API response
2052
+
2053
+ Returns:
2054
+ Union[job.CopyJob, job.ExtractJob, job.LoadJob, job.QueryJob, job.UnknownJob]:
2055
+ The job instance, constructed via the resource.
2056
+ """
2057
+ config = resource.get("configuration", {})
2058
+ if "load" in config:
2059
+ return job.LoadJob.from_api_repr(resource, self)
2060
+ elif "copy" in config:
2061
+ return job.CopyJob.from_api_repr(resource, self)
2062
+ elif "extract" in config:
2063
+ return job.ExtractJob.from_api_repr(resource, self)
2064
+ elif "query" in config:
2065
+ return job.QueryJob.from_api_repr(resource, self)
2066
+ return job.UnknownJob.from_api_repr(resource, self)
2067
+
2068
+ def create_job(
2069
+ self,
2070
+ job_config: dict,
2071
+ retry: retries.Retry = DEFAULT_RETRY,
2072
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
2073
+ ) -> Union[job.LoadJob, job.CopyJob, job.ExtractJob, job.QueryJob]:
2074
+ """Create a new job.
2075
+
2076
+ Args:
2077
+ job_config (dict): configuration job representation returned from the API.
2078
+ retry (Optional[google.api_core.retry.Retry]): How to retry the RPC.
2079
+ timeout (Optional[float]):
2080
+ The number of seconds to wait for the underlying HTTP transport
2081
+ before using ``retry``.
2082
+
2083
+ Returns:
2084
+ Union[ \
2085
+ google.cloud.bigquery.job.LoadJob, \
2086
+ google.cloud.bigquery.job.CopyJob, \
2087
+ google.cloud.bigquery.job.ExtractJob, \
2088
+ google.cloud.bigquery.job.QueryJob \
2089
+ ]:
2090
+ A new job instance.
2091
+ """
2092
+
2093
+ if "load" in job_config:
2094
+ load_job_config = google.cloud.bigquery.job.LoadJobConfig.from_api_repr(
2095
+ job_config
2096
+ )
2097
+ destination = _get_sub_prop(job_config, ["load", "destinationTable"])
2098
+ source_uris = _get_sub_prop(job_config, ["load", "sourceUris"])
2099
+ destination = TableReference.from_api_repr(destination)
2100
+ return self.load_table_from_uri(
2101
+ source_uris,
2102
+ destination,
2103
+ job_config=typing.cast(LoadJobConfig, load_job_config),
2104
+ retry=retry,
2105
+ timeout=timeout,
2106
+ )
2107
+ elif "copy" in job_config:
2108
+ copy_job_config = google.cloud.bigquery.job.CopyJobConfig.from_api_repr(
2109
+ job_config
2110
+ )
2111
+ destination = _get_sub_prop(job_config, ["copy", "destinationTable"])
2112
+ destination = TableReference.from_api_repr(destination)
2113
+ return self.copy_table(
2114
+ [], # Source table(s) already in job_config resource.
2115
+ destination,
2116
+ job_config=typing.cast(CopyJobConfig, copy_job_config),
2117
+ retry=retry,
2118
+ timeout=timeout,
2119
+ )
2120
+ elif "extract" in job_config:
2121
+ extract_job_config = (
2122
+ google.cloud.bigquery.job.ExtractJobConfig.from_api_repr(job_config)
2123
+ )
2124
+ source = _get_sub_prop(job_config, ["extract", "sourceTable"])
2125
+ if source:
2126
+ source_type = "Table"
2127
+ source = TableReference.from_api_repr(source)
2128
+ else:
2129
+ source = _get_sub_prop(job_config, ["extract", "sourceModel"])
2130
+ source_type = "Model"
2131
+ source = ModelReference.from_api_repr(source)
2132
+ destination_uris = _get_sub_prop(job_config, ["extract", "destinationUris"])
2133
+ return self.extract_table(
2134
+ source,
2135
+ destination_uris,
2136
+ job_config=typing.cast(ExtractJobConfig, extract_job_config),
2137
+ retry=retry,
2138
+ timeout=timeout,
2139
+ source_type=source_type,
2140
+ )
2141
+ elif "query" in job_config:
2142
+ query_job_config = google.cloud.bigquery.job.QueryJobConfig.from_api_repr(
2143
+ job_config
2144
+ )
2145
+ query = _get_sub_prop(job_config, ["query", "query"])
2146
+ return self.query(
2147
+ query,
2148
+ job_config=typing.cast(QueryJobConfig, query_job_config),
2149
+ retry=retry,
2150
+ timeout=timeout,
2151
+ )
2152
+ else:
2153
+ raise TypeError("Invalid job configuration received.")
2154
+
2155
+ def get_job(
2156
+ self,
2157
+ job_id: Union[str, job.LoadJob, job.CopyJob, job.ExtractJob, job.QueryJob],
2158
+ project: Optional[str] = None,
2159
+ location: Optional[str] = None,
2160
+ retry: retries.Retry = DEFAULT_RETRY,
2161
+ timeout: TimeoutType = DEFAULT_GET_JOB_TIMEOUT,
2162
+ ) -> Union[job.LoadJob, job.CopyJob, job.ExtractJob, job.QueryJob, job.UnknownJob]:
2163
+ """Fetch a job for the project associated with this client.
2164
+
2165
+ See
2166
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/get
2167
+
2168
+ Args:
2169
+ job_id (Union[ \
2170
+ str, \
2171
+ job.LoadJob, \
2172
+ job.CopyJob, \
2173
+ job.ExtractJob, \
2174
+ job.QueryJob \
2175
+ ]):
2176
+ Job identifier.
2177
+ project (Optional[str]):
2178
+ ID of the project which owns the job (defaults to the client's project).
2179
+ location (Optional[str]):
2180
+ Location where the job was run. Ignored if ``job_id`` is a job
2181
+ object.
2182
+ retry (Optional[google.api_core.retry.Retry]):
2183
+ How to retry the RPC.
2184
+ timeout (Optional[float]):
2185
+ The number of seconds to wait for the underlying HTTP transport
2186
+ before using ``retry``.
2187
+
2188
+ Returns:
2189
+ Union[job.LoadJob, job.CopyJob, job.ExtractJob, job.QueryJob, job.UnknownJob]:
2190
+ Job instance, based on the resource returned by the API.
2191
+ """
2192
+ extra_params = {"projection": "full"}
2193
+
2194
+ project, location, job_id = _extract_job_reference(
2195
+ job_id, project=project, location=location
2196
+ )
2197
+
2198
+ if project is None:
2199
+ project = self.project
2200
+
2201
+ if location is None:
2202
+ location = self.location
2203
+
2204
+ if location is not None:
2205
+ extra_params["location"] = location
2206
+
2207
+ path = "/projects/{}/jobs/{}".format(project, job_id)
2208
+
2209
+ span_attributes = {"path": path, "job_id": job_id, "location": location}
2210
+
2211
+ resource = self._call_api(
2212
+ retry,
2213
+ span_name="BigQuery.getJob",
2214
+ span_attributes=span_attributes,
2215
+ method="GET",
2216
+ path=path,
2217
+ query_params=extra_params,
2218
+ timeout=timeout,
2219
+ )
2220
+
2221
+ return self.job_from_resource(resource)
2222
+
2223
+ def cancel_job(
2224
+ self,
2225
+ job_id: str,
2226
+ project: Optional[str] = None,
2227
+ location: Optional[str] = None,
2228
+ retry: retries.Retry = DEFAULT_RETRY,
2229
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
2230
+ ) -> Union[job.LoadJob, job.CopyJob, job.ExtractJob, job.QueryJob]:
2231
+ """Attempt to cancel a job from a job ID.
2232
+
2233
+ See
2234
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/cancel
2235
+
2236
+ Args:
2237
+ job_id (Union[ \
2238
+ str, \
2239
+ google.cloud.bigquery.job.LoadJob, \
2240
+ google.cloud.bigquery.job.CopyJob, \
2241
+ google.cloud.bigquery.job.ExtractJob, \
2242
+ google.cloud.bigquery.job.QueryJob \
2243
+ ]): Job identifier.
2244
+ project (Optional[str]):
2245
+ ID of the project which owns the job (defaults to the client's project).
2246
+ location (Optional[str]):
2247
+ Location where the job was run. Ignored if ``job_id`` is a job
2248
+ object.
2249
+ retry (Optional[google.api_core.retry.Retry]):
2250
+ How to retry the RPC.
2251
+ timeout (Optional[float]):
2252
+ The number of seconds to wait for the underlying HTTP transport
2253
+ before using ``retry``.
2254
+
2255
+ Returns:
2256
+ Union[ \
2257
+ google.cloud.bigquery.job.LoadJob, \
2258
+ google.cloud.bigquery.job.CopyJob, \
2259
+ google.cloud.bigquery.job.ExtractJob, \
2260
+ google.cloud.bigquery.job.QueryJob, \
2261
+ ]:
2262
+ Job instance, based on the resource returned by the API.
2263
+ """
2264
+ extra_params = {"projection": "full"}
2265
+
2266
+ project, location, job_id = _extract_job_reference(
2267
+ job_id, project=project, location=location
2268
+ )
2269
+
2270
+ if project is None:
2271
+ project = self.project
2272
+
2273
+ if location is None:
2274
+ location = self.location
2275
+
2276
+ if location is not None:
2277
+ extra_params["location"] = location
2278
+
2279
+ path = "/projects/{}/jobs/{}/cancel".format(project, job_id)
2280
+
2281
+ span_attributes = {"path": path, "job_id": job_id, "location": location}
2282
+
2283
+ resource = self._call_api(
2284
+ retry,
2285
+ span_name="BigQuery.cancelJob",
2286
+ span_attributes=span_attributes,
2287
+ method="POST",
2288
+ path=path,
2289
+ query_params=extra_params,
2290
+ timeout=timeout,
2291
+ )
2292
+
2293
+ job_instance = self.job_from_resource(resource["job"]) # never an UnknownJob
2294
+
2295
+ return typing.cast(
2296
+ Union[job.LoadJob, job.CopyJob, job.ExtractJob, job.QueryJob],
2297
+ job_instance,
2298
+ )
2299
+
2300
+ def list_jobs(
2301
+ self,
2302
+ project: Optional[str] = None,
2303
+ parent_job: Optional[Union[QueryJob, str]] = None,
2304
+ max_results: Optional[int] = None,
2305
+ page_token: Optional[str] = None,
2306
+ all_users: Optional[bool] = None,
2307
+ state_filter: Optional[str] = None,
2308
+ retry: retries.Retry = DEFAULT_RETRY,
2309
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
2310
+ min_creation_time: Optional[datetime.datetime] = None,
2311
+ max_creation_time: Optional[datetime.datetime] = None,
2312
+ page_size: Optional[int] = None,
2313
+ ) -> page_iterator.Iterator:
2314
+ """List jobs for the project associated with this client.
2315
+
2316
+ See
2317
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/list
2318
+
2319
+ Args:
2320
+ project (Optional[str]):
2321
+ Project ID to use for retreiving datasets. Defaults
2322
+ to the client's project.
2323
+ parent_job (Optional[Union[ \
2324
+ google.cloud.bigquery.job._AsyncJob, \
2325
+ str, \
2326
+ ]]):
2327
+ If set, retrieve only child jobs of the specified parent.
2328
+ max_results (Optional[int]):
2329
+ Maximum number of jobs to return.
2330
+ page_token (Optional[str]):
2331
+ Opaque marker for the next "page" of jobs. If not
2332
+ passed, the API will return the first page of jobs. The token
2333
+ marks the beginning of the iterator to be returned and the
2334
+ value of the ``page_token`` can be accessed at
2335
+ ``next_page_token`` of
2336
+ :class:`~google.api_core.page_iterator.HTTPIterator`.
2337
+ all_users (Optional[bool]):
2338
+ If true, include jobs owned by all users in the project.
2339
+ Defaults to :data:`False`.
2340
+ state_filter (Optional[str]):
2341
+ If set, include only jobs matching the given state. One of:
2342
+ * ``"done"``
2343
+ * ``"pending"``
2344
+ * ``"running"``
2345
+ retry (Optional[google.api_core.retry.Retry]):
2346
+ How to retry the RPC.
2347
+ timeout (Optional[float]):
2348
+ The number of seconds to wait for the underlying HTTP transport
2349
+ before using ``retry``.
2350
+ min_creation_time (Optional[datetime.datetime]):
2351
+ Min value for job creation time. If set, only jobs created
2352
+ after or at this timestamp are returned. If the datetime has
2353
+ no time zone assumes UTC time.
2354
+ max_creation_time (Optional[datetime.datetime]):
2355
+ Max value for job creation time. If set, only jobs created
2356
+ before or at this timestamp are returned. If the datetime has
2357
+ no time zone assumes UTC time.
2358
+ page_size (Optional[int]):
2359
+ Maximum number of jobs to return per page.
2360
+
2361
+ Returns:
2362
+ google.api_core.page_iterator.Iterator:
2363
+ Iterable of job instances.
2364
+ """
2365
+ if isinstance(parent_job, job._AsyncJob):
2366
+ parent_job = parent_job.job_id # pytype: disable=attribute-error
2367
+
2368
+ extra_params = {
2369
+ "allUsers": all_users,
2370
+ "stateFilter": state_filter,
2371
+ "minCreationTime": _str_or_none(
2372
+ google.cloud._helpers._millis_from_datetime(min_creation_time)
2373
+ ),
2374
+ "maxCreationTime": _str_or_none(
2375
+ google.cloud._helpers._millis_from_datetime(max_creation_time)
2376
+ ),
2377
+ "projection": "full",
2378
+ "parentJobId": parent_job,
2379
+ }
2380
+
2381
+ extra_params = {
2382
+ param: value for param, value in extra_params.items() if value is not None
2383
+ }
2384
+
2385
+ if project is None:
2386
+ project = self.project
2387
+
2388
+ path = "/projects/%s/jobs" % (project,)
2389
+
2390
+ span_attributes = {"path": path}
2391
+
2392
+ def api_request(*args, **kwargs):
2393
+ return self._call_api(
2394
+ retry,
2395
+ span_name="BigQuery.listJobs",
2396
+ span_attributes=span_attributes,
2397
+ *args,
2398
+ timeout=timeout,
2399
+ **kwargs,
2400
+ )
2401
+
2402
+ return page_iterator.HTTPIterator(
2403
+ client=self,
2404
+ api_request=api_request,
2405
+ path=path,
2406
+ item_to_value=_item_to_job,
2407
+ items_key="jobs",
2408
+ page_token=page_token,
2409
+ max_results=max_results,
2410
+ extra_params=extra_params,
2411
+ page_size=page_size,
2412
+ )
2413
+
2414
+ def load_table_from_uri(
2415
+ self,
2416
+ source_uris: Union[str, Sequence[str]],
2417
+ destination: Union[Table, TableReference, TableListItem, str],
2418
+ job_id: Optional[str] = None,
2419
+ job_id_prefix: Optional[str] = None,
2420
+ location: Optional[str] = None,
2421
+ project: Optional[str] = None,
2422
+ job_config: Optional[LoadJobConfig] = None,
2423
+ retry: retries.Retry = DEFAULT_RETRY,
2424
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
2425
+ ) -> job.LoadJob:
2426
+ """Starts a job for loading data into a table from Cloud Storage.
2427
+
2428
+ See
2429
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#jobconfigurationload
2430
+
2431
+ Args:
2432
+ source_uris (Union[str, Sequence[str]]):
2433
+ URIs of data files to be loaded; in format
2434
+ ``gs://<bucket_name>/<object_name_or_glob>``.
2435
+ destination (Union[ \
2436
+ google.cloud.bigquery.table.Table, \
2437
+ google.cloud.bigquery.table.TableReference, \
2438
+ google.cloud.bigquery.table.TableListItem, \
2439
+ str, \
2440
+ ]):
2441
+ Table into which data is to be loaded. If a string is passed
2442
+ in, this method attempts to create a table reference from a
2443
+ string using
2444
+ :func:`google.cloud.bigquery.table.TableReference.from_string`.
2445
+ job_id (Optional[str]): Name of the job.
2446
+ job_id_prefix (Optional[str]):
2447
+ The user-provided prefix for a randomly generated job ID.
2448
+ This parameter will be ignored if a ``job_id`` is also given.
2449
+ location (Optional[str]):
2450
+ Location where to run the job. Must match the location of the
2451
+ destination table.
2452
+ project (Optional[str]):
2453
+ Project ID of the project of where to run the job. Defaults
2454
+ to the client's project.
2455
+ job_config (Optional[google.cloud.bigquery.job.LoadJobConfig]):
2456
+ Extra configuration options for the job.
2457
+ retry (Optional[google.api_core.retry.Retry]):
2458
+ How to retry the RPC.
2459
+ timeout (Optional[float]):
2460
+ The number of seconds to wait for the underlying HTTP transport
2461
+ before using ``retry``.
2462
+
2463
+ Returns:
2464
+ google.cloud.bigquery.job.LoadJob: A new load job.
2465
+
2466
+ Raises:
2467
+ TypeError:
2468
+ If ``job_config`` is not an instance of
2469
+ :class:`~google.cloud.bigquery.job.LoadJobConfig` class.
2470
+ """
2471
+ job_id = _make_job_id(job_id, job_id_prefix)
2472
+
2473
+ if project is None:
2474
+ project = self.project
2475
+
2476
+ if location is None:
2477
+ location = self.location
2478
+
2479
+ job_ref = job._JobReference(job_id, project=project, location=location)
2480
+
2481
+ if isinstance(source_uris, str):
2482
+ source_uris = [source_uris]
2483
+
2484
+ destination = _table_arg_to_table_ref(destination, default_project=self.project)
2485
+
2486
+ if job_config is not None:
2487
+ _verify_job_config_type(job_config, LoadJobConfig)
2488
+ else:
2489
+ job_config = job.LoadJobConfig()
2490
+
2491
+ new_job_config = job_config._fill_from_default(self._default_load_job_config)
2492
+
2493
+ load_job = job.LoadJob(job_ref, source_uris, destination, self, new_job_config)
2494
+ load_job._begin(retry=retry, timeout=timeout)
2495
+
2496
+ return load_job
2497
+
2498
+ def load_table_from_file(
2499
+ self,
2500
+ file_obj: IO[bytes],
2501
+ destination: Union[Table, TableReference, TableListItem, str],
2502
+ rewind: bool = False,
2503
+ size: Optional[int] = None,
2504
+ num_retries: int = _DEFAULT_NUM_RETRIES,
2505
+ job_id: Optional[str] = None,
2506
+ job_id_prefix: Optional[str] = None,
2507
+ location: Optional[str] = None,
2508
+ project: Optional[str] = None,
2509
+ job_config: Optional[LoadJobConfig] = None,
2510
+ timeout: ResumableTimeoutType = DEFAULT_TIMEOUT,
2511
+ ) -> job.LoadJob:
2512
+ """Upload the contents of this table from a file-like object.
2513
+
2514
+ Similar to :meth:`load_table_from_uri`, this method creates, starts and
2515
+ returns a :class:`~google.cloud.bigquery.job.LoadJob`.
2516
+
2517
+ Args:
2518
+ file_obj (IO[bytes]):
2519
+ A file handle opened in binary mode for reading.
2520
+ destination (Union[Table, \
2521
+ TableReference, \
2522
+ TableListItem, \
2523
+ str \
2524
+ ]):
2525
+ Table into which data is to be loaded. If a string is passed
2526
+ in, this method attempts to create a table reference from a
2527
+ string using
2528
+ :func:`google.cloud.bigquery.table.TableReference.from_string`.
2529
+ rewind (Optional[bool]):
2530
+ If True, seek to the beginning of the file handle before
2531
+ reading the file. Defaults to False.
2532
+ size (Optional[int]):
2533
+ The number of bytes to read from the file handle. If size is
2534
+ ``None`` or large, resumable upload will be used. Otherwise,
2535
+ multipart upload will be used.
2536
+ num_retries (Optional[int]): Number of upload retries. Defaults to 6.
2537
+ job_id (Optional[str]): Name of the job.
2538
+ job_id_prefix (Optional[str]):
2539
+ The user-provided prefix for a randomly generated job ID.
2540
+ This parameter will be ignored if a ``job_id`` is also given.
2541
+ location (Optional[str]):
2542
+ Location where to run the job. Must match the location of the
2543
+ destination table.
2544
+ project (Optional[str]):
2545
+ Project ID of the project of where to run the job. Defaults
2546
+ to the client's project.
2547
+ job_config (Optional[LoadJobConfig]):
2548
+ Extra configuration options for the job.
2549
+ timeout (Optional[float]):
2550
+ The number of seconds to wait for the underlying HTTP transport
2551
+ before using ``retry``. Depending on the retry strategy, a request
2552
+ may be repeated several times using the same timeout each time.
2553
+ Defaults to None.
2554
+
2555
+ Can also be passed as a tuple (connect_timeout, read_timeout).
2556
+ See :meth:`requests.Session.request` documentation for details.
2557
+
2558
+ Returns:
2559
+ google.cloud.bigquery.job.LoadJob: A new load job.
2560
+
2561
+ Raises:
2562
+ ValueError:
2563
+ If ``size`` is not passed in and can not be determined, or if
2564
+ the ``file_obj`` can be detected to be a file opened in text
2565
+ mode.
2566
+
2567
+ TypeError:
2568
+ If ``job_config`` is not an instance of
2569
+ :class:`~google.cloud.bigquery.job.LoadJobConfig` class.
2570
+ """
2571
+ job_id = _make_job_id(job_id, job_id_prefix)
2572
+
2573
+ if project is None:
2574
+ project = self.project
2575
+
2576
+ if location is None:
2577
+ location = self.location
2578
+
2579
+ destination = _table_arg_to_table_ref(destination, default_project=self.project)
2580
+ job_ref = job._JobReference(job_id, project=project, location=location)
2581
+
2582
+ if job_config is not None:
2583
+ _verify_job_config_type(job_config, LoadJobConfig)
2584
+ else:
2585
+ job_config = job.LoadJobConfig()
2586
+
2587
+ new_job_config = job_config._fill_from_default(self._default_load_job_config)
2588
+
2589
+ load_job = job.LoadJob(job_ref, None, destination, self, new_job_config)
2590
+ job_resource = load_job.to_api_repr()
2591
+
2592
+ if rewind:
2593
+ file_obj.seek(0, os.SEEK_SET)
2594
+
2595
+ _check_mode(file_obj)
2596
+
2597
+ try:
2598
+ if size is None or size >= _MAX_MULTIPART_SIZE:
2599
+ response = self._do_resumable_upload(
2600
+ file_obj, job_resource, num_retries, timeout, project=project
2601
+ )
2602
+ else:
2603
+ response = self._do_multipart_upload(
2604
+ file_obj, job_resource, size, num_retries, timeout, project=project
2605
+ )
2606
+ except resumable_media.InvalidResponse as exc:
2607
+ raise exceptions.from_http_response(exc.response)
2608
+
2609
+ return typing.cast(LoadJob, self.job_from_resource(response.json()))
2610
+
2611
+ def load_table_from_dataframe(
2612
+ self,
2613
+ dataframe: "pandas.DataFrame", # type: ignore
2614
+ destination: Union[Table, TableReference, str],
2615
+ num_retries: int = _DEFAULT_NUM_RETRIES,
2616
+ job_id: Optional[str] = None,
2617
+ job_id_prefix: Optional[str] = None,
2618
+ location: Optional[str] = None,
2619
+ project: Optional[str] = None,
2620
+ job_config: Optional[LoadJobConfig] = None,
2621
+ parquet_compression: str = "snappy",
2622
+ timeout: ResumableTimeoutType = DEFAULT_TIMEOUT,
2623
+ ) -> job.LoadJob:
2624
+ """Upload the contents of a table from a pandas DataFrame.
2625
+
2626
+ Similar to :meth:`load_table_from_uri`, this method creates, starts and
2627
+ returns a :class:`~google.cloud.bigquery.job.LoadJob`.
2628
+
2629
+ .. note::
2630
+
2631
+ REPEATED fields are NOT supported when using the CSV source format.
2632
+ They are supported when using the PARQUET source format, but
2633
+ due to the way they are encoded in the ``parquet`` file,
2634
+ a mismatch with the existing table schema can occur, so
2635
+ REPEATED fields are not properly supported when using ``pyarrow<4.0.0``
2636
+ using the parquet format.
2637
+
2638
+ https://github.com/googleapis/python-bigquery/issues/19
2639
+
2640
+ Args:
2641
+ dataframe (pandas.Dataframe):
2642
+ A :class:`~pandas.DataFrame` containing the data to load.
2643
+ destination (Union[ \
2644
+ Table, \
2645
+ TableReference, \
2646
+ str \
2647
+ ]):
2648
+ The destination table to use for loading the data. If it is an
2649
+ existing table, the schema of the :class:`~pandas.DataFrame`
2650
+ must match the schema of the destination table. If the table
2651
+ does not yet exist, the schema is inferred from the
2652
+ :class:`~pandas.DataFrame`.
2653
+
2654
+ If a string is passed in, this method attempts to create a
2655
+ table reference from a string using
2656
+ :func:`google.cloud.bigquery.table.TableReference.from_string`.
2657
+ num_retries (Optional[int]): Number of upload retries. Defaults to 6.
2658
+ job_id (Optional[str]): Name of the job.
2659
+ job_id_prefix (Optional[str]):
2660
+ The user-provided prefix for a randomly generated
2661
+ job ID. This parameter will be ignored if a ``job_id`` is
2662
+ also given.
2663
+ location (Optional[str]):
2664
+ Location where to run the job. Must match the location of the
2665
+ destination table.
2666
+ project (Optional[str]):
2667
+ Project ID of the project of where to run the job. Defaults
2668
+ to the client's project.
2669
+ job_config (Optional[LoadJobConfig]):
2670
+ Extra configuration options for the job.
2671
+
2672
+ To override the default pandas data type conversions, supply
2673
+ a value for
2674
+ :attr:`~google.cloud.bigquery.job.LoadJobConfig.schema` with
2675
+ column names matching those of the dataframe. The BigQuery
2676
+ schema is used to determine the correct data type conversion.
2677
+ Indexes are not loaded.
2678
+
2679
+ By default, this method uses the parquet source format. To
2680
+ override this, supply a value for
2681
+ :attr:`~google.cloud.bigquery.job.LoadJobConfig.source_format`
2682
+ with the format name. Currently only
2683
+ :attr:`~google.cloud.bigquery.job.SourceFormat.CSV` and
2684
+ :attr:`~google.cloud.bigquery.job.SourceFormat.PARQUET` are
2685
+ supported.
2686
+ parquet_compression (Optional[str]):
2687
+ [Beta] The compression method to use if intermittently
2688
+ serializing ``dataframe`` to a parquet file.
2689
+ Defaults to "snappy".
2690
+
2691
+ The argument is directly passed as the ``compression``
2692
+ argument to the underlying ``pyarrow.parquet.write_table()``
2693
+ method (the default value "snappy" gets converted to uppercase).
2694
+ https://arrow.apache.org/docs/python/generated/pyarrow.parquet.write_table.html#pyarrow-parquet-write-table
2695
+
2696
+ If the job config schema is missing, the argument is directly
2697
+ passed as the ``compression`` argument to the underlying
2698
+ ``DataFrame.to_parquet()`` method.
2699
+ https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_parquet.html#pandas.DataFrame.to_parquet
2700
+ timeout (Optional[flaot]):
2701
+ The number of seconds to wait for the underlying HTTP transport
2702
+ before using ``retry``. Depending on the retry strategy, a request may
2703
+ be repeated several times using the same timeout each time.
2704
+ Defaults to None.
2705
+
2706
+ Can also be passed as a tuple (connect_timeout, read_timeout).
2707
+ See :meth:`requests.Session.request` documentation for details.
2708
+
2709
+ Returns:
2710
+ google.cloud.bigquery.job.LoadJob: A new load job.
2711
+
2712
+ Raises:
2713
+ ValueError:
2714
+ If a usable parquet engine cannot be found. This method
2715
+ requires :mod:`pyarrow` to be installed.
2716
+ TypeError:
2717
+ If ``job_config`` is not an instance of
2718
+ :class:`~google.cloud.bigquery.job.LoadJobConfig` class.
2719
+ """
2720
+ job_id = _make_job_id(job_id, job_id_prefix)
2721
+
2722
+ if job_config is not None:
2723
+ _verify_job_config_type(job_config, LoadJobConfig)
2724
+ else:
2725
+ job_config = job.LoadJobConfig()
2726
+
2727
+ new_job_config = job_config._fill_from_default(self._default_load_job_config)
2728
+
2729
+ supported_formats = {job.SourceFormat.CSV, job.SourceFormat.PARQUET}
2730
+ if new_job_config.source_format is None:
2731
+ # default value
2732
+ new_job_config.source_format = job.SourceFormat.PARQUET
2733
+
2734
+ if (
2735
+ new_job_config.source_format == job.SourceFormat.PARQUET
2736
+ and new_job_config.parquet_options is None
2737
+ ):
2738
+ parquet_options = ParquetOptions()
2739
+ # default value
2740
+ parquet_options.enable_list_inference = True
2741
+ new_job_config.parquet_options = parquet_options
2742
+
2743
+ if new_job_config.source_format not in supported_formats:
2744
+ raise ValueError(
2745
+ "Got unexpected source_format: '{}'. Currently, only PARQUET and CSV are supported".format(
2746
+ new_job_config.source_format
2747
+ )
2748
+ )
2749
+
2750
+ if pyarrow is None and new_job_config.source_format == job.SourceFormat.PARQUET:
2751
+ # pyarrow is now the only supported parquet engine.
2752
+ raise ValueError("This method requires pyarrow to be installed")
2753
+
2754
+ if location is None:
2755
+ location = self.location
2756
+
2757
+ # If table schema is not provided, we try to fetch the existing table
2758
+ # schema, and check if dataframe schema is compatible with it - except
2759
+ # for WRITE_TRUNCATE jobs, the existing schema does not matter then.
2760
+ if (
2761
+ not new_job_config.schema
2762
+ and new_job_config.write_disposition != job.WriteDisposition.WRITE_TRUNCATE
2763
+ ):
2764
+ try:
2765
+ table = self.get_table(destination)
2766
+ except core_exceptions.NotFound:
2767
+ pass
2768
+ else:
2769
+ columns_and_indexes = frozenset(
2770
+ name
2771
+ for name, _ in _pandas_helpers.list_columns_and_indexes(dataframe)
2772
+ )
2773
+ new_job_config.schema = [
2774
+ # Field description and policy tags are not needed to
2775
+ # serialize a data frame.
2776
+ SchemaField(
2777
+ field.name,
2778
+ field.field_type,
2779
+ mode=field.mode,
2780
+ fields=field.fields,
2781
+ )
2782
+ # schema fields not present in the dataframe are not needed
2783
+ for field in table.schema
2784
+ if field.name in columns_and_indexes
2785
+ ]
2786
+
2787
+ new_job_config.schema = _pandas_helpers.dataframe_to_bq_schema(
2788
+ dataframe, new_job_config.schema
2789
+ )
2790
+
2791
+ if not new_job_config.schema:
2792
+ # the schema could not be fully detected
2793
+ warnings.warn(
2794
+ "Schema could not be detected for all columns. Loading from a "
2795
+ "dataframe without a schema will be deprecated in the future, "
2796
+ "please provide a schema.",
2797
+ PendingDeprecationWarning,
2798
+ stacklevel=2,
2799
+ )
2800
+
2801
+ tmpfd, tmppath = tempfile.mkstemp(
2802
+ suffix="_job_{}.{}".format(job_id[:8], new_job_config.source_format.lower())
2803
+ )
2804
+ os.close(tmpfd)
2805
+
2806
+ try:
2807
+ if new_job_config.source_format == job.SourceFormat.PARQUET:
2808
+ if new_job_config.schema:
2809
+ if parquet_compression == "snappy": # adjust the default value
2810
+ parquet_compression = parquet_compression.upper()
2811
+
2812
+ _pandas_helpers.dataframe_to_parquet(
2813
+ dataframe,
2814
+ new_job_config.schema,
2815
+ tmppath,
2816
+ parquet_compression=parquet_compression,
2817
+ parquet_use_compliant_nested_type=True,
2818
+ )
2819
+ else:
2820
+ dataframe.to_parquet(
2821
+ tmppath,
2822
+ engine="pyarrow",
2823
+ compression=parquet_compression,
2824
+ **(
2825
+ {"use_compliant_nested_type": True}
2826
+ if _versions_helpers.PYARROW_VERSIONS.use_compliant_nested_type
2827
+ else {}
2828
+ ),
2829
+ )
2830
+
2831
+ else:
2832
+ dataframe.to_csv(
2833
+ tmppath,
2834
+ index=False,
2835
+ header=False,
2836
+ encoding="utf-8",
2837
+ float_format="%.17g",
2838
+ date_format="%Y-%m-%d %H:%M:%S.%f",
2839
+ )
2840
+
2841
+ with open(tmppath, "rb") as tmpfile:
2842
+ file_size = os.path.getsize(tmppath)
2843
+ return self.load_table_from_file(
2844
+ tmpfile,
2845
+ destination,
2846
+ num_retries=num_retries,
2847
+ rewind=True,
2848
+ size=file_size,
2849
+ job_id=job_id,
2850
+ job_id_prefix=job_id_prefix,
2851
+ location=location,
2852
+ project=project,
2853
+ job_config=new_job_config,
2854
+ timeout=timeout,
2855
+ )
2856
+
2857
+ finally:
2858
+ os.remove(tmppath)
2859
+
2860
+ def load_table_from_json(
2861
+ self,
2862
+ json_rows: Iterable[Dict[str, Any]],
2863
+ destination: Union[Table, TableReference, TableListItem, str],
2864
+ num_retries: int = _DEFAULT_NUM_RETRIES,
2865
+ job_id: Optional[str] = None,
2866
+ job_id_prefix: Optional[str] = None,
2867
+ location: Optional[str] = None,
2868
+ project: Optional[str] = None,
2869
+ job_config: Optional[LoadJobConfig] = None,
2870
+ timeout: ResumableTimeoutType = DEFAULT_TIMEOUT,
2871
+ ) -> job.LoadJob:
2872
+ """Upload the contents of a table from a JSON string or dict.
2873
+
2874
+ Args:
2875
+ json_rows (Iterable[Dict[str, Any]]):
2876
+ Row data to be inserted. Keys must match the table schema fields
2877
+ and values must be JSON-compatible representations.
2878
+
2879
+ .. note::
2880
+
2881
+ If your data is already a newline-delimited JSON string,
2882
+ it is best to wrap it into a file-like object and pass it
2883
+ to :meth:`~google.cloud.bigquery.client.Client.load_table_from_file`::
2884
+
2885
+ import io
2886
+ from google.cloud import bigquery
2887
+
2888
+ data = u'{"foo": "bar"}'
2889
+ data_as_file = io.StringIO(data)
2890
+
2891
+ client = bigquery.Client()
2892
+ client.load_table_from_file(data_as_file, ...)
2893
+
2894
+ destination (Union[ \
2895
+ Table, \
2896
+ TableReference, \
2897
+ TableListItem, \
2898
+ str \
2899
+ ]):
2900
+ Table into which data is to be loaded. If a string is passed
2901
+ in, this method attempts to create a table reference from a
2902
+ string using
2903
+ :func:`google.cloud.bigquery.table.TableReference.from_string`.
2904
+ num_retries (Optional[int]): Number of upload retries. Defaults to 6.
2905
+ job_id (Optional[str]): Name of the job.
2906
+ job_id_prefix (Optional[str]):
2907
+ The user-provided prefix for a randomly generated job ID.
2908
+ This parameter will be ignored if a ``job_id`` is also given.
2909
+ location (Optional[str]):
2910
+ Location where to run the job. Must match the location of the
2911
+ destination table.
2912
+ project (Optional[str]):
2913
+ Project ID of the project of where to run the job. Defaults
2914
+ to the client's project.
2915
+ job_config (Optional[LoadJobConfig]):
2916
+ Extra configuration options for the job. The ``source_format``
2917
+ setting is always set to
2918
+ :attr:`~google.cloud.bigquery.job.SourceFormat.NEWLINE_DELIMITED_JSON`.
2919
+ timeout (Optional[float]):
2920
+ The number of seconds to wait for the underlying HTTP transport
2921
+ before using ``retry``. Depending on the retry strategy, a request may
2922
+ be repeated several times using the same timeout each time.
2923
+ Defaults to None.
2924
+
2925
+ Can also be passed as a tuple (connect_timeout, read_timeout).
2926
+ See :meth:`requests.Session.request` documentation for details.
2927
+
2928
+ Returns:
2929
+ google.cloud.bigquery.job.LoadJob: A new load job.
2930
+
2931
+ Raises:
2932
+ TypeError:
2933
+ If ``job_config`` is not an instance of
2934
+ :class:`~google.cloud.bigquery.job.LoadJobConfig` class.
2935
+ """
2936
+ job_id = _make_job_id(job_id, job_id_prefix)
2937
+
2938
+ if job_config is not None:
2939
+ _verify_job_config_type(job_config, LoadJobConfig)
2940
+ else:
2941
+ job_config = job.LoadJobConfig()
2942
+
2943
+ new_job_config = job_config._fill_from_default(self._default_load_job_config)
2944
+
2945
+ new_job_config.source_format = job.SourceFormat.NEWLINE_DELIMITED_JSON
2946
+
2947
+ # In specific conditions, we check if the table alread exists, and/or
2948
+ # set the autodetect value for the user. For exact conditions, see table
2949
+ # https://github.com/googleapis/python-bigquery/issues/1228#issuecomment-1910946297
2950
+ if new_job_config.schema is None and new_job_config.autodetect is None:
2951
+ if new_job_config.write_disposition in (
2952
+ job.WriteDisposition.WRITE_TRUNCATE,
2953
+ job.WriteDisposition.WRITE_EMPTY,
2954
+ ):
2955
+ new_job_config.autodetect = True
2956
+ else:
2957
+ try:
2958
+ self.get_table(destination)
2959
+ except core_exceptions.NotFound:
2960
+ new_job_config.autodetect = True
2961
+ else:
2962
+ new_job_config.autodetect = False
2963
+
2964
+ if project is None:
2965
+ project = self.project
2966
+
2967
+ if location is None:
2968
+ location = self.location
2969
+
2970
+ destination = _table_arg_to_table_ref(destination, default_project=self.project)
2971
+
2972
+ data_str = "\n".join(json.dumps(item, ensure_ascii=False) for item in json_rows)
2973
+ encoded_str = data_str.encode()
2974
+ data_file = io.BytesIO(encoded_str)
2975
+ return self.load_table_from_file(
2976
+ data_file,
2977
+ destination,
2978
+ size=len(encoded_str),
2979
+ num_retries=num_retries,
2980
+ job_id=job_id,
2981
+ job_id_prefix=job_id_prefix,
2982
+ location=location,
2983
+ project=project,
2984
+ job_config=new_job_config,
2985
+ timeout=timeout,
2986
+ )
2987
+
2988
+ def _do_resumable_upload(
2989
+ self,
2990
+ stream: IO[bytes],
2991
+ metadata: Mapping[str, str],
2992
+ num_retries: int,
2993
+ timeout: Optional[ResumableTimeoutType],
2994
+ project: Optional[str] = None,
2995
+ ) -> "requests.Response":
2996
+ """Perform a resumable upload.
2997
+
2998
+ Args:
2999
+ stream (IO[bytes]): A bytes IO object open for reading.
3000
+ metadata (Mapping[str, str]): The metadata associated with the upload.
3001
+ num_retries (int):
3002
+ Number of upload retries. (Deprecated: This
3003
+ argument will be removed in a future release.)
3004
+ timeout (Optional[float]):
3005
+ The number of seconds to wait for the underlying HTTP transport
3006
+ before using ``retry``. Depending on the retry strategy, a request may
3007
+ be repeated several times using the same timeout each time.
3008
+
3009
+ Can also be passed as a tuple (connect_timeout, read_timeout).
3010
+ See :meth:`requests.Session.request` documentation for details.
3011
+ project (Optional[str]):
3012
+ Project ID of the project of where to run the upload. Defaults
3013
+ to the client's project.
3014
+
3015
+ Returns:
3016
+ The "200 OK" response object returned after the final chunk
3017
+ is uploaded.
3018
+ """
3019
+ upload, transport = self._initiate_resumable_upload(
3020
+ stream, metadata, num_retries, timeout, project=project
3021
+ )
3022
+
3023
+ while not upload.finished:
3024
+ response = upload.transmit_next_chunk(transport, timeout=timeout)
3025
+
3026
+ return response
3027
+
3028
+ def _initiate_resumable_upload(
3029
+ self,
3030
+ stream: IO[bytes],
3031
+ metadata: Mapping[str, str],
3032
+ num_retries: int,
3033
+ timeout: Optional[ResumableTimeoutType],
3034
+ project: Optional[str] = None,
3035
+ ):
3036
+ """Initiate a resumable upload.
3037
+
3038
+ Args:
3039
+ stream (IO[bytes]): A bytes IO object open for reading.
3040
+ metadata (Mapping[str, str]): The metadata associated with the upload.
3041
+ num_retries (int):
3042
+ Number of upload retries. (Deprecated: This
3043
+ argument will be removed in a future release.)
3044
+ timeout (Optional[float]):
3045
+ The number of seconds to wait for the underlying HTTP transport
3046
+ before using ``retry``. Depending on the retry strategy, a request may
3047
+ be repeated several times using the same timeout each time.
3048
+
3049
+ Can also be passed as a tuple (connect_timeout, read_timeout).
3050
+ See :meth:`requests.Session.request` documentation for details.
3051
+ project (Optional[str]):
3052
+ Project ID of the project of where to run the upload. Defaults
3053
+ to the client's project.
3054
+
3055
+ Returns:
3056
+ Tuple:
3057
+ Pair of
3058
+
3059
+ * The :class:`~google.resumable_media.requests.ResumableUpload`
3060
+ that was created
3061
+ * The ``transport`` used to initiate the upload.
3062
+ """
3063
+ chunk_size = _DEFAULT_CHUNKSIZE
3064
+ transport = self._http
3065
+ headers = _get_upload_headers(self._connection.user_agent)
3066
+
3067
+ if project is None:
3068
+ project = self.project
3069
+ # TODO: Increase the minimum version of google-cloud-core to 1.6.0
3070
+ # and remove this logic. See:
3071
+ # https://github.com/googleapis/python-bigquery/issues/509
3072
+ hostname = (
3073
+ self._connection.API_BASE_URL
3074
+ if not hasattr(self._connection, "get_api_base_url_for_mtls")
3075
+ else self._connection.get_api_base_url_for_mtls()
3076
+ )
3077
+ upload_url = _RESUMABLE_URL_TEMPLATE.format(host=hostname, project=project)
3078
+
3079
+ # TODO: modify ResumableUpload to take a retry.Retry object
3080
+ # that it can use for the initial RPC.
3081
+ upload = ResumableUpload(upload_url, chunk_size, headers=headers)
3082
+
3083
+ if num_retries is not None:
3084
+ upload._retry_strategy = resumable_media.RetryStrategy(
3085
+ max_retries=num_retries
3086
+ )
3087
+
3088
+ upload.initiate(
3089
+ transport,
3090
+ stream,
3091
+ metadata,
3092
+ _GENERIC_CONTENT_TYPE,
3093
+ stream_final=False,
3094
+ timeout=timeout,
3095
+ )
3096
+
3097
+ return upload, transport
3098
+
3099
+ def _do_multipart_upload(
3100
+ self,
3101
+ stream: IO[bytes],
3102
+ metadata: Mapping[str, str],
3103
+ size: int,
3104
+ num_retries: int,
3105
+ timeout: Optional[ResumableTimeoutType],
3106
+ project: Optional[str] = None,
3107
+ ):
3108
+ """Perform a multipart upload.
3109
+
3110
+ Args:
3111
+ stream (IO[bytes]): A bytes IO object open for reading.
3112
+ metadata (Mapping[str, str]): The metadata associated with the upload.
3113
+ size (int):
3114
+ The number of bytes to be uploaded (which will be read
3115
+ from ``stream``). If not provided, the upload will be
3116
+ concluded once ``stream`` is exhausted (or :data:`None`).
3117
+ num_retries (int):
3118
+ Number of upload retries. (Deprecated: This
3119
+ argument will be removed in a future release.)
3120
+ timeout (Optional[float]):
3121
+ The number of seconds to wait for the underlying HTTP transport
3122
+ before using ``retry``. Depending on the retry strategy, a request may
3123
+ be repeated several times using the same timeout each time.
3124
+
3125
+ Can also be passed as a tuple (connect_timeout, read_timeout).
3126
+ See :meth:`requests.Session.request` documentation for details.
3127
+ project (Optional[str]):
3128
+ Project ID of the project of where to run the upload. Defaults
3129
+ to the client's project.
3130
+
3131
+ Returns:
3132
+ requests.Response:
3133
+ The "200 OK" response object returned after the multipart
3134
+ upload request.
3135
+
3136
+ Raises:
3137
+ ValueError:
3138
+ if the ``stream`` has fewer than ``size``
3139
+ bytes remaining.
3140
+ """
3141
+ data = stream.read(size)
3142
+ if len(data) < size:
3143
+ msg = _READ_LESS_THAN_SIZE.format(size, len(data))
3144
+ raise ValueError(msg)
3145
+
3146
+ headers = _get_upload_headers(self._connection.user_agent)
3147
+
3148
+ if project is None:
3149
+ project = self.project
3150
+
3151
+ # TODO: Increase the minimum version of google-cloud-core to 1.6.0
3152
+ # and remove this logic. See:
3153
+ # https://github.com/googleapis/python-bigquery/issues/509
3154
+ hostname = (
3155
+ self._connection.API_BASE_URL
3156
+ if not hasattr(self._connection, "get_api_base_url_for_mtls")
3157
+ else self._connection.get_api_base_url_for_mtls()
3158
+ )
3159
+ upload_url = _MULTIPART_URL_TEMPLATE.format(host=hostname, project=project)
3160
+ upload = MultipartUpload(upload_url, headers=headers)
3161
+
3162
+ if num_retries is not None:
3163
+ upload._retry_strategy = resumable_media.RetryStrategy(
3164
+ max_retries=num_retries
3165
+ )
3166
+
3167
+ response = upload.transmit(
3168
+ self._http, data, metadata, _GENERIC_CONTENT_TYPE, timeout=timeout
3169
+ )
3170
+
3171
+ return response
3172
+
3173
+ def copy_table(
3174
+ self,
3175
+ sources: Union[
3176
+ Table,
3177
+ TableReference,
3178
+ TableListItem,
3179
+ str,
3180
+ Sequence[Union[Table, TableReference, TableListItem, str]],
3181
+ ],
3182
+ destination: Union[Table, TableReference, TableListItem, str],
3183
+ job_id: Optional[str] = None,
3184
+ job_id_prefix: Optional[str] = None,
3185
+ location: Optional[str] = None,
3186
+ project: Optional[str] = None,
3187
+ job_config: Optional[CopyJobConfig] = None,
3188
+ retry: retries.Retry = DEFAULT_RETRY,
3189
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
3190
+ ) -> job.CopyJob:
3191
+ """Copy one or more tables to another table.
3192
+
3193
+ See
3194
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#jobconfigurationtablecopy
3195
+
3196
+ Args:
3197
+ sources (Union[ \
3198
+ google.cloud.bigquery.table.Table, \
3199
+ google.cloud.bigquery.table.TableReference, \
3200
+ google.cloud.bigquery.table.TableListItem, \
3201
+ str, \
3202
+ Sequence[ \
3203
+ Union[ \
3204
+ google.cloud.bigquery.table.Table, \
3205
+ google.cloud.bigquery.table.TableReference, \
3206
+ google.cloud.bigquery.table.TableListItem, \
3207
+ str, \
3208
+ ] \
3209
+ ], \
3210
+ ]):
3211
+ Table or tables to be copied.
3212
+ destination (Union[ \
3213
+ google.cloud.bigquery.table.Table, \
3214
+ google.cloud.bigquery.table.TableReference, \
3215
+ google.cloud.bigquery.table.TableListItem, \
3216
+ str, \
3217
+ ]):
3218
+ Table into which data is to be copied.
3219
+ job_id (Optional[str]): The ID of the job.
3220
+ job_id_prefix (Optional[str]):
3221
+ The user-provided prefix for a randomly generated job ID.
3222
+ This parameter will be ignored if a ``job_id`` is also given.
3223
+ location (Optional[str]):
3224
+ Location where to run the job. Must match the location of any
3225
+ source table as well as the destination table.
3226
+ project (Optional[str]):
3227
+ Project ID of the project of where to run the job. Defaults
3228
+ to the client's project.
3229
+ job_config (Optional[google.cloud.bigquery.job.CopyJobConfig]):
3230
+ Extra configuration options for the job.
3231
+ retry (Optional[google.api_core.retry.Retry]):
3232
+ How to retry the RPC.
3233
+ timeout (Optional[float]):
3234
+ The number of seconds to wait for the underlying HTTP transport
3235
+ before using ``retry``.
3236
+
3237
+ Returns:
3238
+ google.cloud.bigquery.job.CopyJob: A new copy job instance.
3239
+
3240
+ Raises:
3241
+ TypeError:
3242
+ If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.CopyJobConfig`
3243
+ class.
3244
+ """
3245
+ job_id = _make_job_id(job_id, job_id_prefix)
3246
+
3247
+ if project is None:
3248
+ project = self.project
3249
+
3250
+ if location is None:
3251
+ location = self.location
3252
+
3253
+ job_ref = job._JobReference(job_id, project=project, location=location)
3254
+
3255
+ # sources can be one of many different input types. (string, Table,
3256
+ # TableReference, or a sequence of any of those.) Convert them all to a
3257
+ # list of TableReferences.
3258
+ #
3259
+ # _table_arg_to_table_ref leaves lists unmodified.
3260
+ sources = _table_arg_to_table_ref(sources, default_project=self.project)
3261
+
3262
+ if not isinstance(sources, collections_abc.Sequence):
3263
+ sources = [sources]
3264
+
3265
+ sources = [
3266
+ _table_arg_to_table_ref(source, default_project=self.project)
3267
+ for source in sources
3268
+ ]
3269
+
3270
+ destination = _table_arg_to_table_ref(destination, default_project=self.project)
3271
+
3272
+ if job_config:
3273
+ _verify_job_config_type(job_config, google.cloud.bigquery.job.CopyJobConfig)
3274
+ job_config = copy.deepcopy(job_config)
3275
+
3276
+ copy_job = job.CopyJob(
3277
+ job_ref, sources, destination, client=self, job_config=job_config
3278
+ )
3279
+ copy_job._begin(retry=retry, timeout=timeout)
3280
+
3281
+ return copy_job
3282
+
3283
+ def extract_table(
3284
+ self,
3285
+ source: Union[Table, TableReference, TableListItem, Model, ModelReference, str],
3286
+ destination_uris: Union[str, Sequence[str]],
3287
+ job_id: Optional[str] = None,
3288
+ job_id_prefix: Optional[str] = None,
3289
+ location: Optional[str] = None,
3290
+ project: Optional[str] = None,
3291
+ job_config: Optional[ExtractJobConfig] = None,
3292
+ retry: retries.Retry = DEFAULT_RETRY,
3293
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
3294
+ source_type: str = "Table",
3295
+ ) -> job.ExtractJob:
3296
+ """Start a job to extract a table into Cloud Storage files.
3297
+
3298
+ See
3299
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#jobconfigurationextract
3300
+
3301
+ Args:
3302
+ source (Union[ \
3303
+ google.cloud.bigquery.table.Table, \
3304
+ google.cloud.bigquery.table.TableReference, \
3305
+ google.cloud.bigquery.table.TableListItem, \
3306
+ google.cloud.bigquery.model.Model, \
3307
+ google.cloud.bigquery.model.ModelReference, \
3308
+ src, \
3309
+ ]):
3310
+ Table or Model to be extracted.
3311
+ destination_uris (Union[str, Sequence[str]]):
3312
+ URIs of Cloud Storage file(s) into which table data is to be
3313
+ extracted; in format
3314
+ ``gs://<bucket_name>/<object_name_or_glob>``.
3315
+ job_id (Optional[str]): The ID of the job.
3316
+ job_id_prefix (Optional[str]):
3317
+ The user-provided prefix for a randomly generated job ID.
3318
+ This parameter will be ignored if a ``job_id`` is also given.
3319
+ location (Optional[str]):
3320
+ Location where to run the job. Must match the location of the
3321
+ source table.
3322
+ project (Optional[str]):
3323
+ Project ID of the project of where to run the job. Defaults
3324
+ to the client's project.
3325
+ job_config (Optional[google.cloud.bigquery.job.ExtractJobConfig]):
3326
+ Extra configuration options for the job.
3327
+ retry (Optional[google.api_core.retry.Retry]):
3328
+ How to retry the RPC.
3329
+ timeout (Optional[float]):
3330
+ The number of seconds to wait for the underlying HTTP transport
3331
+ before using ``retry``.
3332
+ source_type (Optional[str]):
3333
+ Type of source to be extracted.``Table`` or ``Model``. Defaults to ``Table``.
3334
+ Returns:
3335
+ google.cloud.bigquery.job.ExtractJob: A new extract job instance.
3336
+
3337
+ Raises:
3338
+ TypeError:
3339
+ If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.ExtractJobConfig`
3340
+ class.
3341
+ ValueError:
3342
+ If ``source_type`` is not among ``Table``,``Model``.
3343
+ """
3344
+ job_id = _make_job_id(job_id, job_id_prefix)
3345
+
3346
+ if project is None:
3347
+ project = self.project
3348
+
3349
+ if location is None:
3350
+ location = self.location
3351
+
3352
+ job_ref = job._JobReference(job_id, project=project, location=location)
3353
+ src = source_type.lower()
3354
+ if src == "table":
3355
+ source = _table_arg_to_table_ref(source, default_project=self.project)
3356
+ elif src == "model":
3357
+ source = _model_arg_to_model_ref(source, default_project=self.project)
3358
+ else:
3359
+ raise ValueError(
3360
+ "Cannot pass `{}` as a ``source_type``, pass Table or Model".format(
3361
+ source_type
3362
+ )
3363
+ )
3364
+
3365
+ if isinstance(destination_uris, str):
3366
+ destination_uris = [destination_uris]
3367
+
3368
+ if job_config:
3369
+ _verify_job_config_type(
3370
+ job_config, google.cloud.bigquery.job.ExtractJobConfig
3371
+ )
3372
+ job_config = copy.deepcopy(job_config)
3373
+
3374
+ extract_job = job.ExtractJob(
3375
+ job_ref, source, destination_uris, client=self, job_config=job_config
3376
+ )
3377
+ extract_job._begin(retry=retry, timeout=timeout)
3378
+
3379
+ return extract_job
3380
+
3381
+ def query(
3382
+ self,
3383
+ query: str,
3384
+ job_config: Optional[QueryJobConfig] = None,
3385
+ job_id: Optional[str] = None,
3386
+ job_id_prefix: Optional[str] = None,
3387
+ location: Optional[str] = None,
3388
+ project: Optional[str] = None,
3389
+ retry: retries.Retry = DEFAULT_RETRY,
3390
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
3391
+ job_retry: retries.Retry = DEFAULT_JOB_RETRY,
3392
+ api_method: Union[str, enums.QueryApiMethod] = enums.QueryApiMethod.INSERT,
3393
+ ) -> job.QueryJob:
3394
+ """Run a SQL query.
3395
+
3396
+ See
3397
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#jobconfigurationquery
3398
+
3399
+ Args:
3400
+ query (str):
3401
+ SQL query to be executed. Defaults to the standard SQL
3402
+ dialect. Use the ``job_config`` parameter to change dialects.
3403
+ job_config (Optional[google.cloud.bigquery.job.QueryJobConfig]):
3404
+ Extra configuration options for the job.
3405
+ To override any options that were previously set in
3406
+ the ``default_query_job_config`` given to the
3407
+ ``Client`` constructor, manually set those options to ``None``,
3408
+ or whatever value is preferred.
3409
+ job_id (Optional[str]): ID to use for the query job.
3410
+ job_id_prefix (Optional[str]):
3411
+ The prefix to use for a randomly generated job ID. This parameter
3412
+ will be ignored if a ``job_id`` is also given.
3413
+ location (Optional[str]):
3414
+ Location where to run the job. Must match the location of the
3415
+ table used in the query as well as the destination table.
3416
+ project (Optional[str]):
3417
+ Project ID of the project of where to run the job. Defaults
3418
+ to the client's project.
3419
+ retry (Optional[google.api_core.retry.Retry]):
3420
+ How to retry the RPC. This only applies to making RPC
3421
+ calls. It isn't used to retry failed jobs. This has
3422
+ a reasonable default that should only be overridden
3423
+ with care.
3424
+ timeout (Optional[float]):
3425
+ The number of seconds to wait for the underlying HTTP transport
3426
+ before using ``retry``.
3427
+ job_retry (Optional[google.api_core.retry.Retry]):
3428
+ How to retry failed jobs. The default retries
3429
+ rate-limit-exceeded errors. Passing ``None`` disables
3430
+ job retry.
3431
+
3432
+ Not all jobs can be retried. If ``job_id`` is
3433
+ provided, then the job returned by the query will not
3434
+ be retryable, and an exception will be raised if a
3435
+ non-``None`` (and non-default) value for ``job_retry``
3436
+ is also provided.
3437
+
3438
+ Note that errors aren't detected until ``result()`` is
3439
+ called on the job returned. The ``job_retry``
3440
+ specified here becomes the default ``job_retry`` for
3441
+ ``result()``, where it can also be specified.
3442
+ api_method (Union[str, enums.QueryApiMethod]):
3443
+ Method with which to start the query job.
3444
+
3445
+ See :class:`google.cloud.bigquery.enums.QueryApiMethod` for
3446
+ details on the difference between the query start methods.
3447
+
3448
+ Returns:
3449
+ google.cloud.bigquery.job.QueryJob: A new query job instance.
3450
+
3451
+ Raises:
3452
+ TypeError:
3453
+ If ``job_config`` is not an instance of
3454
+ :class:`~google.cloud.bigquery.job.QueryJobConfig`
3455
+ class, or if both ``job_id`` and non-``None`` non-default
3456
+ ``job_retry`` are provided.
3457
+ """
3458
+ job_id_given = job_id is not None
3459
+ if (
3460
+ job_id_given
3461
+ and job_retry is not None
3462
+ and job_retry is not DEFAULT_JOB_RETRY
3463
+ ):
3464
+ raise TypeError(
3465
+ "`job_retry` was provided, but the returned job is"
3466
+ " not retryable, because a custom `job_id` was"
3467
+ " provided."
3468
+ )
3469
+
3470
+ if job_id_given and api_method == enums.QueryApiMethod.QUERY:
3471
+ raise TypeError(
3472
+ "`job_id` was provided, but the 'QUERY' `api_method` was requested."
3473
+ )
3474
+
3475
+ if project is None:
3476
+ project = self.project
3477
+
3478
+ if location is None:
3479
+ location = self.location
3480
+
3481
+ if job_config is not None:
3482
+ _verify_job_config_type(job_config, QueryJobConfig)
3483
+
3484
+ job_config = _job_helpers.job_config_with_defaults(
3485
+ job_config, self._default_query_job_config
3486
+ )
3487
+
3488
+ # Note that we haven't modified the original job_config (or
3489
+ # _default_query_job_config) up to this point.
3490
+ if api_method == enums.QueryApiMethod.QUERY:
3491
+ return _job_helpers.query_jobs_query(
3492
+ self,
3493
+ query,
3494
+ job_config,
3495
+ location,
3496
+ project,
3497
+ retry,
3498
+ timeout,
3499
+ job_retry,
3500
+ )
3501
+ elif api_method == enums.QueryApiMethod.INSERT:
3502
+ return _job_helpers.query_jobs_insert(
3503
+ self,
3504
+ query,
3505
+ job_config,
3506
+ job_id,
3507
+ job_id_prefix,
3508
+ location,
3509
+ project,
3510
+ retry,
3511
+ timeout,
3512
+ job_retry,
3513
+ )
3514
+ else:
3515
+ raise ValueError(f"Got unexpected value for api_method: {repr(api_method)}")
3516
+
3517
+ def query_and_wait(
3518
+ self,
3519
+ query,
3520
+ *,
3521
+ job_config: Optional[QueryJobConfig] = None,
3522
+ location: Optional[str] = None,
3523
+ project: Optional[str] = None,
3524
+ api_timeout: TimeoutType = DEFAULT_TIMEOUT,
3525
+ wait_timeout: Union[Optional[float], object] = POLLING_DEFAULT_VALUE,
3526
+ retry: retries.Retry = DEFAULT_RETRY,
3527
+ job_retry: retries.Retry = DEFAULT_JOB_RETRY,
3528
+ page_size: Optional[int] = None,
3529
+ max_results: Optional[int] = None,
3530
+ ) -> RowIterator:
3531
+ """Run the query, wait for it to finish, and return the results.
3532
+
3533
+ While ``jobCreationMode=JOB_CREATION_OPTIONAL`` is in preview in the
3534
+ ``jobs.query`` REST API, use the default ``jobCreationMode`` unless
3535
+ the environment variable ``QUERY_PREVIEW_ENABLED=true``. After
3536
+ ``jobCreationMode`` is GA, this method will always use
3537
+ ``jobCreationMode=JOB_CREATION_OPTIONAL``. See:
3538
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query
3539
+
3540
+ Args:
3541
+ query (str):
3542
+ SQL query to be executed. Defaults to the standard SQL
3543
+ dialect. Use the ``job_config`` parameter to change dialects.
3544
+ job_config (Optional[google.cloud.bigquery.job.QueryJobConfig]):
3545
+ Extra configuration options for the job.
3546
+ To override any options that were previously set in
3547
+ the ``default_query_job_config`` given to the
3548
+ ``Client`` constructor, manually set those options to ``None``,
3549
+ or whatever value is preferred.
3550
+ location (Optional[str]):
3551
+ Location where to run the job. Must match the location of the
3552
+ table used in the query as well as the destination table.
3553
+ project (Optional[str]):
3554
+ Project ID of the project of where to run the job. Defaults
3555
+ to the client's project.
3556
+ api_timeout (Optional[float]):
3557
+ The number of seconds to wait for the underlying HTTP transport
3558
+ before using ``retry``.
3559
+ wait_timeout (Optional[Union[float, object]]):
3560
+ The number of seconds to wait for the query to finish. If the
3561
+ query doesn't finish before this timeout, the client attempts
3562
+ to cancel the query. If unset, the underlying REST API calls
3563
+ have timeouts, but we still wait indefinitely for the job to
3564
+ finish.
3565
+ retry (Optional[google.api_core.retry.Retry]):
3566
+ How to retry the RPC. This only applies to making RPC
3567
+ calls. It isn't used to retry failed jobs. This has
3568
+ a reasonable default that should only be overridden
3569
+ with care.
3570
+ job_retry (Optional[google.api_core.retry.Retry]):
3571
+ How to retry failed jobs. The default retries
3572
+ rate-limit-exceeded errors. Passing ``None`` disables
3573
+ job retry. Not all jobs can be retried.
3574
+ page_size (Optional[int]):
3575
+ The maximum number of rows in each page of results from this
3576
+ request. Non-positive values are ignored.
3577
+ max_results (Optional[int]):
3578
+ The maximum total number of rows from this request.
3579
+
3580
+ Returns:
3581
+ google.cloud.bigquery.table.RowIterator:
3582
+ Iterator of row data
3583
+ :class:`~google.cloud.bigquery.table.Row`-s. During each
3584
+ page, the iterator will have the ``total_rows`` attribute
3585
+ set, which counts the total number of rows **in the result
3586
+ set** (this is distinct from the total number of rows in the
3587
+ current page: ``iterator.page.num_items``).
3588
+
3589
+ If the query is a special query that produces no results, e.g.
3590
+ a DDL query, an ``_EmptyRowIterator`` instance is returned.
3591
+
3592
+ Raises:
3593
+ TypeError:
3594
+ If ``job_config`` is not an instance of
3595
+ :class:`~google.cloud.bigquery.job.QueryJobConfig`
3596
+ class.
3597
+ """
3598
+ if project is None:
3599
+ project = self.project
3600
+
3601
+ if location is None:
3602
+ location = self.location
3603
+
3604
+ if job_config is not None:
3605
+ _verify_job_config_type(job_config, QueryJobConfig)
3606
+
3607
+ job_config = _job_helpers.job_config_with_defaults(
3608
+ job_config, self._default_query_job_config
3609
+ )
3610
+
3611
+ return _job_helpers.query_and_wait(
3612
+ self,
3613
+ query,
3614
+ job_config=job_config,
3615
+ location=location,
3616
+ project=project,
3617
+ api_timeout=api_timeout,
3618
+ wait_timeout=wait_timeout,
3619
+ retry=retry,
3620
+ job_retry=job_retry,
3621
+ page_size=page_size,
3622
+ max_results=max_results,
3623
+ )
3624
+
3625
+ def insert_rows(
3626
+ self,
3627
+ table: Union[Table, TableReference, str],
3628
+ rows: Union[Iterable[Tuple], Iterable[Mapping[str, Any]]],
3629
+ selected_fields: Optional[Sequence[SchemaField]] = None,
3630
+ **kwargs,
3631
+ ) -> Sequence[Dict[str, Any]]:
3632
+ """Insert rows into a table via the streaming API.
3633
+
3634
+ See
3635
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/tabledata/insertAll
3636
+
3637
+ BigQuery will reject insertAll payloads that exceed a defined limit (10MB).
3638
+ Additionally, if a payload vastly exceeds this limit, the request is rejected
3639
+ by the intermediate architecture, which returns a 413 (Payload Too Large) status code.
3640
+
3641
+
3642
+ See
3643
+ https://cloud.google.com/bigquery/quotas#streaming_inserts
3644
+
3645
+ Args:
3646
+ table (Union[ \
3647
+ google.cloud.bigquery.table.Table, \
3648
+ google.cloud.bigquery.table.TableReference, \
3649
+ str, \
3650
+ ]):
3651
+ The destination table for the row data, or a reference to it.
3652
+ rows (Union[Sequence[Tuple], Sequence[Dict]]):
3653
+ Row data to be inserted. If a list of tuples is given, each
3654
+ tuple should contain data for each schema field on the
3655
+ current table and in the same order as the schema fields. If
3656
+ a list of dictionaries is given, the keys must include all
3657
+ required fields in the schema. Keys which do not correspond
3658
+ to a field in the schema are ignored.
3659
+ selected_fields (Sequence[google.cloud.bigquery.schema.SchemaField]):
3660
+ The fields to return. Required if ``table`` is a
3661
+ :class:`~google.cloud.bigquery.table.TableReference`.
3662
+ kwargs (dict):
3663
+ Keyword arguments to
3664
+ :meth:`~google.cloud.bigquery.client.Client.insert_rows_json`.
3665
+
3666
+ Returns:
3667
+ Sequence[Mappings]:
3668
+ One mapping per row with insert errors: the "index" key
3669
+ identifies the row, and the "errors" key contains a list of
3670
+ the mappings describing one or more problems with the row.
3671
+
3672
+ Raises:
3673
+ ValueError: if table's schema is not set or `rows` is not a `Sequence`.
3674
+ """
3675
+ if not isinstance(rows, (collections_abc.Sequence, collections_abc.Iterator)):
3676
+ raise TypeError("rows argument should be a sequence of dicts or tuples")
3677
+
3678
+ table = _table_arg_to_table(table, default_project=self.project)
3679
+
3680
+ if not isinstance(table, Table):
3681
+ raise TypeError(_NEED_TABLE_ARGUMENT)
3682
+
3683
+ schema = table.schema
3684
+
3685
+ # selected_fields can override the table schema.
3686
+ if selected_fields is not None:
3687
+ schema = selected_fields
3688
+
3689
+ if len(schema) == 0:
3690
+ raise ValueError(
3691
+ (
3692
+ "Could not determine schema for table '{}'. Call client.get_table() "
3693
+ "or pass in a list of schema fields to the selected_fields argument."
3694
+ ).format(table)
3695
+ )
3696
+
3697
+ json_rows = [_record_field_to_json(schema, row) for row in rows]
3698
+
3699
+ return self.insert_rows_json(table, json_rows, **kwargs)
3700
+
3701
+ def insert_rows_from_dataframe(
3702
+ self,
3703
+ table: Union[Table, TableReference, str],
3704
+ dataframe,
3705
+ selected_fields: Optional[Sequence[SchemaField]] = None,
3706
+ chunk_size: int = 500,
3707
+ **kwargs: Dict,
3708
+ ) -> Sequence[Sequence[dict]]:
3709
+ """Insert rows into a table from a dataframe via the streaming API.
3710
+
3711
+ BigQuery will reject insertAll payloads that exceed a defined limit (10MB).
3712
+ Additionally, if a payload vastly exceeds this limit, the request is rejected
3713
+ by the intermediate architecture, which returns a 413 (Payload Too Large) status code.
3714
+
3715
+ See
3716
+ https://cloud.google.com/bigquery/quotas#streaming_inserts
3717
+
3718
+ Args:
3719
+ table (Union[ \
3720
+ google.cloud.bigquery.table.Table, \
3721
+ google.cloud.bigquery.table.TableReference, \
3722
+ str, \
3723
+ ]):
3724
+ The destination table for the row data, or a reference to it.
3725
+ dataframe (pandas.DataFrame):
3726
+ A :class:`~pandas.DataFrame` containing the data to load. Any
3727
+ ``NaN`` values present in the dataframe are omitted from the
3728
+ streaming API request(s).
3729
+ selected_fields (Sequence[google.cloud.bigquery.schema.SchemaField]):
3730
+ The fields to return. Required if ``table`` is a
3731
+ :class:`~google.cloud.bigquery.table.TableReference`.
3732
+ chunk_size (int):
3733
+ The number of rows to stream in a single chunk. Must be positive.
3734
+ kwargs (Dict):
3735
+ Keyword arguments to
3736
+ :meth:`~google.cloud.bigquery.client.Client.insert_rows_json`.
3737
+
3738
+ Returns:
3739
+ Sequence[Sequence[Mappings]]:
3740
+ A list with insert errors for each insert chunk. Each element
3741
+ is a list containing one mapping per row with insert errors:
3742
+ the "index" key identifies the row, and the "errors" key
3743
+ contains a list of the mappings describing one or more problems
3744
+ with the row.
3745
+
3746
+ Raises:
3747
+ ValueError: if table's schema is not set
3748
+ """
3749
+ insert_results = []
3750
+
3751
+ chunk_count = int(math.ceil(len(dataframe) / chunk_size))
3752
+ rows_iter = _pandas_helpers.dataframe_to_json_generator(dataframe)
3753
+
3754
+ for _ in range(chunk_count):
3755
+ rows_chunk = itertools.islice(rows_iter, chunk_size)
3756
+ result = self.insert_rows(table, rows_chunk, selected_fields, **kwargs)
3757
+ insert_results.append(result)
3758
+
3759
+ return insert_results
3760
+
3761
+ def insert_rows_json(
3762
+ self,
3763
+ table: Union[Table, TableReference, TableListItem, str],
3764
+ json_rows: Sequence[Mapping[str, Any]],
3765
+ row_ids: Union[
3766
+ Iterable[Optional[str]], AutoRowIDs, None
3767
+ ] = AutoRowIDs.GENERATE_UUID,
3768
+ skip_invalid_rows: Optional[bool] = None,
3769
+ ignore_unknown_values: Optional[bool] = None,
3770
+ template_suffix: Optional[str] = None,
3771
+ retry: retries.Retry = DEFAULT_RETRY,
3772
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
3773
+ ) -> Sequence[dict]:
3774
+ """Insert rows into a table without applying local type conversions.
3775
+
3776
+ See
3777
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/tabledata/insertAll
3778
+
3779
+ BigQuery will reject insertAll payloads that exceed a defined limit (10MB).
3780
+ Additionally, if a payload vastly exceeds this limit, the request is rejected
3781
+ by the intermediate architecture, which returns a 413 (Payload Too Large) status code.
3782
+
3783
+ See
3784
+ https://cloud.google.com/bigquery/quotas#streaming_inserts
3785
+
3786
+ Args:
3787
+ table (Union[ \
3788
+ google.cloud.bigquery.table.Table \
3789
+ google.cloud.bigquery.table.TableReference, \
3790
+ google.cloud.bigquery.table.TableListItem, \
3791
+ str \
3792
+ ]):
3793
+ The destination table for the row data, or a reference to it.
3794
+ json_rows (Sequence[Dict]):
3795
+ Row data to be inserted. Keys must match the table schema fields
3796
+ and values must be JSON-compatible representations.
3797
+ row_ids (Union[Iterable[str], AutoRowIDs, None]):
3798
+ Unique IDs, one per row being inserted. An ID can also be
3799
+ ``None``, indicating that an explicit insert ID should **not**
3800
+ be used for that row. If the argument is omitted altogether,
3801
+ unique IDs are created automatically.
3802
+
3803
+ .. versionchanged:: 2.21.0
3804
+ Can also be an iterable, not just a sequence, or an
3805
+ :class:`AutoRowIDs` enum member.
3806
+
3807
+ .. deprecated:: 2.21.0
3808
+ Passing ``None`` to explicitly request autogenerating insert IDs is
3809
+ deprecated, use :attr:`AutoRowIDs.GENERATE_UUID` instead.
3810
+
3811
+ skip_invalid_rows (Optional[bool]):
3812
+ Insert all valid rows of a request, even if invalid rows exist.
3813
+ The default value is ``False``, which causes the entire request
3814
+ to fail if any invalid rows exist.
3815
+ ignore_unknown_values (Optional[bool]):
3816
+ Accept rows that contain values that do not match the schema.
3817
+ The unknown values are ignored. Default is ``False``, which
3818
+ treats unknown values as errors.
3819
+ template_suffix (Optional[str]):
3820
+ Treat ``name`` as a template table and provide a suffix.
3821
+ BigQuery will create the table ``<name> + <template_suffix>``
3822
+ based on the schema of the template table. See
3823
+ https://cloud.google.com/bigquery/streaming-data-into-bigquery#template-tables
3824
+ retry (Optional[google.api_core.retry.Retry]):
3825
+ How to retry the RPC.
3826
+ timeout (Optional[float]):
3827
+ The number of seconds to wait for the underlying HTTP transport
3828
+ before using ``retry``.
3829
+
3830
+ Returns:
3831
+ Sequence[Mappings]:
3832
+ One mapping per row with insert errors: the "index" key
3833
+ identifies the row, and the "errors" key contains a list of
3834
+ the mappings describing one or more problems with the row.
3835
+
3836
+ Raises:
3837
+ TypeError: if `json_rows` is not a `Sequence`.
3838
+ """
3839
+ if not isinstance(
3840
+ json_rows, (collections_abc.Sequence, collections_abc.Iterator)
3841
+ ):
3842
+ raise TypeError("json_rows argument should be a sequence of dicts")
3843
+ # Convert table to just a reference because unlike insert_rows,
3844
+ # insert_rows_json doesn't need the table schema. It's not doing any
3845
+ # type conversions.
3846
+ table = _table_arg_to_table_ref(table, default_project=self.project)
3847
+ rows_info: List[Any] = []
3848
+ data: Dict[str, Any] = {"rows": rows_info}
3849
+
3850
+ if row_ids is None:
3851
+ warnings.warn(
3852
+ "Passing None for row_ids is deprecated. To explicitly request "
3853
+ "autogenerated insert IDs, use AutoRowIDs.GENERATE_UUID instead",
3854
+ category=DeprecationWarning,
3855
+ )
3856
+ row_ids = AutoRowIDs.GENERATE_UUID
3857
+
3858
+ if not isinstance(row_ids, AutoRowIDs):
3859
+ try:
3860
+ row_ids_iter = iter(row_ids)
3861
+ except TypeError:
3862
+ msg = "row_ids is neither an iterable nor an AutoRowIDs enum member"
3863
+ raise TypeError(msg)
3864
+
3865
+ for i, row in enumerate(json_rows):
3866
+ info: Dict[str, Any] = {"json": row}
3867
+
3868
+ if row_ids is AutoRowIDs.GENERATE_UUID:
3869
+ info["insertId"] = str(uuid.uuid4())
3870
+ elif row_ids is AutoRowIDs.DISABLED:
3871
+ info["insertId"] = None
3872
+ else:
3873
+ try:
3874
+ insert_id = next(row_ids_iter)
3875
+ except StopIteration:
3876
+ msg = f"row_ids did not generate enough IDs, error at index {i}"
3877
+ raise ValueError(msg)
3878
+ else:
3879
+ info["insertId"] = insert_id
3880
+
3881
+ rows_info.append(info)
3882
+
3883
+ if skip_invalid_rows is not None:
3884
+ data["skipInvalidRows"] = skip_invalid_rows
3885
+
3886
+ if ignore_unknown_values is not None:
3887
+ data["ignoreUnknownValues"] = ignore_unknown_values
3888
+
3889
+ if template_suffix is not None:
3890
+ data["templateSuffix"] = template_suffix
3891
+
3892
+ path = "%s/insertAll" % table.path
3893
+ # We can always retry, because every row has an insert ID.
3894
+ span_attributes = {"path": path}
3895
+ response = self._call_api(
3896
+ retry,
3897
+ span_name="BigQuery.insertRowsJson",
3898
+ span_attributes=span_attributes,
3899
+ method="POST",
3900
+ path=path,
3901
+ data=data,
3902
+ timeout=timeout,
3903
+ )
3904
+ errors = []
3905
+
3906
+ for error in response.get("insertErrors", ()):
3907
+ errors.append({"index": int(error["index"]), "errors": error["errors"]})
3908
+
3909
+ return errors
3910
+
3911
+ def list_partitions(
3912
+ self,
3913
+ table: Union[Table, TableReference, TableListItem, str],
3914
+ retry: retries.Retry = DEFAULT_RETRY,
3915
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
3916
+ ) -> Sequence[str]:
3917
+ """List the partitions in a table.
3918
+
3919
+ Args:
3920
+ table (Union[ \
3921
+ google.cloud.bigquery.table.Table, \
3922
+ google.cloud.bigquery.table.TableReference, \
3923
+ google.cloud.bigquery.table.TableListItem, \
3924
+ str, \
3925
+ ]):
3926
+ The table or reference from which to get partition info
3927
+ retry (Optional[google.api_core.retry.Retry]):
3928
+ How to retry the RPC.
3929
+ timeout (Optional[float]):
3930
+ The number of seconds to wait for the underlying HTTP transport
3931
+ before using ``retry``.
3932
+ If multiple requests are made under the hood, ``timeout``
3933
+ applies to each individual request.
3934
+
3935
+ Returns:
3936
+ List[str]:
3937
+ A list of the partition ids present in the partitioned table
3938
+ """
3939
+ table = _table_arg_to_table_ref(table, default_project=self.project)
3940
+ meta_table = self.get_table(
3941
+ TableReference(
3942
+ DatasetReference(table.project, table.dataset_id),
3943
+ "%s$__PARTITIONS_SUMMARY__" % table.table_id,
3944
+ ),
3945
+ retry=retry,
3946
+ timeout=timeout,
3947
+ )
3948
+
3949
+ subset = [col for col in meta_table.schema if col.name == "partition_id"]
3950
+ return [
3951
+ row[0]
3952
+ for row in self.list_rows(
3953
+ meta_table, selected_fields=subset, retry=retry, timeout=timeout
3954
+ )
3955
+ ]
3956
+
3957
+ def list_rows(
3958
+ self,
3959
+ table: Union[Table, TableListItem, TableReference, str],
3960
+ selected_fields: Optional[Sequence[SchemaField]] = None,
3961
+ max_results: Optional[int] = None,
3962
+ page_token: Optional[str] = None,
3963
+ start_index: Optional[int] = None,
3964
+ page_size: Optional[int] = None,
3965
+ retry: retries.Retry = DEFAULT_RETRY,
3966
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
3967
+ ) -> RowIterator:
3968
+ """List the rows of the table.
3969
+
3970
+ See
3971
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/tabledata/list
3972
+
3973
+ .. note::
3974
+
3975
+ This method assumes that the provided schema is up-to-date with the
3976
+ schema as defined on the back-end: if the two schemas are not
3977
+ identical, the values returned may be incomplete. To ensure that the
3978
+ local copy of the schema is up-to-date, call ``client.get_table``.
3979
+
3980
+ Args:
3981
+ table (Union[ \
3982
+ google.cloud.bigquery.table.Table, \
3983
+ google.cloud.bigquery.table.TableListItem, \
3984
+ google.cloud.bigquery.table.TableReference, \
3985
+ str, \
3986
+ ]):
3987
+ The table to list, or a reference to it. When the table
3988
+ object does not contain a schema and ``selected_fields`` is
3989
+ not supplied, this method calls ``get_table`` to fetch the
3990
+ table schema.
3991
+ selected_fields (Sequence[google.cloud.bigquery.schema.SchemaField]):
3992
+ The fields to return. If not supplied, data for all columns
3993
+ are downloaded.
3994
+ max_results (Optional[int]):
3995
+ Maximum number of rows to return.
3996
+ page_token (Optional[str]):
3997
+ Token representing a cursor into the table's rows.
3998
+ If not passed, the API will return the first page of the
3999
+ rows. The token marks the beginning of the iterator to be
4000
+ returned and the value of the ``page_token`` can be accessed
4001
+ at ``next_page_token`` of the
4002
+ :class:`~google.cloud.bigquery.table.RowIterator`.
4003
+ start_index (Optional[int]):
4004
+ The zero-based index of the starting row to read.
4005
+ page_size (Optional[int]):
4006
+ The maximum number of rows in each page of results from this request.
4007
+ Non-positive values are ignored. Defaults to a sensible value set by the API.
4008
+ retry (Optional[google.api_core.retry.Retry]):
4009
+ How to retry the RPC.
4010
+ timeout (Optional[float]):
4011
+ The number of seconds to wait for the underlying HTTP transport
4012
+ before using ``retry``.
4013
+ If multiple requests are made under the hood, ``timeout``
4014
+ applies to each individual request.
4015
+
4016
+ Returns:
4017
+ google.cloud.bigquery.table.RowIterator:
4018
+ Iterator of row data
4019
+ :class:`~google.cloud.bigquery.table.Row`-s. During each
4020
+ page, the iterator will have the ``total_rows`` attribute
4021
+ set, which counts the total number of rows **in the table**
4022
+ (this is distinct from the total number of rows in the
4023
+ current page: ``iterator.page.num_items``).
4024
+ """
4025
+ table = _table_arg_to_table(table, default_project=self.project)
4026
+
4027
+ if not isinstance(table, Table):
4028
+ raise TypeError(_NEED_TABLE_ARGUMENT)
4029
+
4030
+ schema = table.schema
4031
+
4032
+ # selected_fields can override the table schema.
4033
+ if selected_fields is not None:
4034
+ schema = selected_fields
4035
+
4036
+ # No schema, but no selected_fields. Assume the developer wants all
4037
+ # columns, so get the table resource for them rather than failing.
4038
+ elif len(schema) == 0:
4039
+ table = self.get_table(table.reference, retry=retry, timeout=timeout)
4040
+ schema = table.schema
4041
+
4042
+ params: Dict[str, Any] = {}
4043
+ if selected_fields is not None:
4044
+ params["selectedFields"] = ",".join(field.name for field in selected_fields)
4045
+ if start_index is not None:
4046
+ params["startIndex"] = start_index
4047
+
4048
+ params["formatOptions.useInt64Timestamp"] = True
4049
+ row_iterator = RowIterator(
4050
+ client=self,
4051
+ api_request=functools.partial(self._call_api, retry, timeout=timeout),
4052
+ path="%s/data" % (table.path,),
4053
+ schema=schema,
4054
+ page_token=page_token,
4055
+ max_results=max_results,
4056
+ page_size=page_size,
4057
+ extra_params=params,
4058
+ table=table,
4059
+ # Pass in selected_fields separately from schema so that full
4060
+ # tables can be fetched without a column filter.
4061
+ selected_fields=selected_fields,
4062
+ total_rows=getattr(table, "num_rows", None),
4063
+ project=table.project,
4064
+ location=table.location,
4065
+ )
4066
+ return row_iterator
4067
+
4068
+ def _list_rows_from_query_results(
4069
+ self,
4070
+ job_id: str,
4071
+ location: str,
4072
+ project: str,
4073
+ schema: Sequence[SchemaField],
4074
+ total_rows: Optional[int] = None,
4075
+ destination: Optional[Union[Table, TableReference, TableListItem, str]] = None,
4076
+ max_results: Optional[int] = None,
4077
+ start_index: Optional[int] = None,
4078
+ page_size: Optional[int] = None,
4079
+ retry: retries.Retry = DEFAULT_RETRY,
4080
+ timeout: TimeoutType = DEFAULT_TIMEOUT,
4081
+ query_id: Optional[str] = None,
4082
+ first_page_response: Optional[Dict[str, Any]] = None,
4083
+ num_dml_affected_rows: Optional[int] = None,
4084
+ query: Optional[str] = None,
4085
+ total_bytes_processed: Optional[int] = None,
4086
+ ) -> RowIterator:
4087
+ """List the rows of a completed query.
4088
+ See
4089
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/getQueryResults
4090
+ Args:
4091
+ job_id (str):
4092
+ ID of a query job.
4093
+ location (str): Location of the query job.
4094
+ project (str):
4095
+ ID of the project where the query job was run.
4096
+ schema (Sequence[google.cloud.bigquery.schema.SchemaField]):
4097
+ The fields expected in these query results. Used to convert
4098
+ from JSON to expected Python types.
4099
+ total_rows (Optional[int]):
4100
+ Total number of rows in the query results.
4101
+ destination (Optional[Union[ \
4102
+ google.cloud.bigquery.table.Table, \
4103
+ google.cloud.bigquery.table.TableListItem, \
4104
+ google.cloud.bigquery.table.TableReference, \
4105
+ str, \
4106
+ ]]):
4107
+ Destination table reference. Used to fetch the query results
4108
+ with the BigQuery Storage API.
4109
+ max_results (Optional[int]):
4110
+ Maximum number of rows to return across the whole iterator.
4111
+ start_index (Optional[int]):
4112
+ The zero-based index of the starting row to read.
4113
+ page_size (Optional[int]):
4114
+ The maximum number of rows in each page of results from this request.
4115
+ Non-positive values are ignored. Defaults to a sensible value set by the API.
4116
+ retry (Optional[google.api_core.retry.Retry]):
4117
+ How to retry the RPC.
4118
+ timeout (Optional[float]):
4119
+ The number of seconds to wait for the underlying HTTP transport
4120
+ before using ``retry``. If set, this connection timeout may be
4121
+ increased to a minimum value. This prevents retries on what
4122
+ would otherwise be a successful response.
4123
+ If multiple requests are made under the hood, ``timeout``
4124
+ applies to each individual request.
4125
+ query_id (Optional[str]):
4126
+ [Preview] ID of a completed query. This ID is auto-generated
4127
+ and not guaranteed to be populated.
4128
+ first_page_response (Optional[dict]):
4129
+ API response for the first page of results (if available).
4130
+ num_dml_affected_rows (Optional[int]):
4131
+ If this RowIterator is the result of a DML query, the number of
4132
+ rows that were affected.
4133
+ query (Optional[str]):
4134
+ The query text used.
4135
+ total_bytes_processed (Optinal[int]):
4136
+ total bytes processed from job statistics, if present.
4137
+
4138
+ Returns:
4139
+ google.cloud.bigquery.table.RowIterator:
4140
+ Iterator of row data
4141
+ :class:`~google.cloud.bigquery.table.Row`-s.
4142
+ """
4143
+ params: Dict[str, Any] = {
4144
+ "fields": _LIST_ROWS_FROM_QUERY_RESULTS_FIELDS,
4145
+ "location": location,
4146
+ }
4147
+
4148
+ if timeout is not None:
4149
+ if not isinstance(timeout, (int, float)):
4150
+ timeout = _MIN_GET_QUERY_RESULTS_TIMEOUT
4151
+ else:
4152
+ timeout = max(timeout, _MIN_GET_QUERY_RESULTS_TIMEOUT)
4153
+
4154
+ if start_index is not None:
4155
+ params["startIndex"] = start_index
4156
+
4157
+ params["formatOptions.useInt64Timestamp"] = True
4158
+ row_iterator = RowIterator(
4159
+ client=self,
4160
+ api_request=functools.partial(self._call_api, retry, timeout=timeout),
4161
+ path=f"/projects/{project}/queries/{job_id}",
4162
+ schema=schema,
4163
+ max_results=max_results,
4164
+ page_size=page_size,
4165
+ table=destination,
4166
+ extra_params=params,
4167
+ total_rows=total_rows,
4168
+ project=project,
4169
+ location=location,
4170
+ job_id=job_id,
4171
+ query_id=query_id,
4172
+ first_page_response=first_page_response,
4173
+ num_dml_affected_rows=num_dml_affected_rows,
4174
+ query=query,
4175
+ total_bytes_processed=total_bytes_processed,
4176
+ )
4177
+ return row_iterator
4178
+
4179
+ def _schema_from_json_file_object(self, file_obj):
4180
+ """Helper function for schema_from_json that takes a
4181
+ file object that describes a table schema.
4182
+
4183
+ Returns:
4184
+ List of schema field objects.
4185
+ """
4186
+ json_data = json.load(file_obj)
4187
+ return [SchemaField.from_api_repr(field) for field in json_data]
4188
+
4189
+ def _schema_to_json_file_object(self, schema_list, file_obj):
4190
+ """Helper function for schema_to_json that takes a schema list and file
4191
+ object and writes the schema list to the file object with json.dump
4192
+ """
4193
+ json.dump(schema_list, file_obj, indent=2, sort_keys=True)
4194
+
4195
+ def schema_from_json(self, file_or_path: "PathType") -> List[SchemaField]:
4196
+ """Takes a file object or file path that contains json that describes
4197
+ a table schema.
4198
+
4199
+ Returns:
4200
+ List[SchemaField]:
4201
+ List of :class:`~google.cloud.bigquery.schema.SchemaField` objects.
4202
+ """
4203
+ if isinstance(file_or_path, io.IOBase):
4204
+ return self._schema_from_json_file_object(file_or_path)
4205
+
4206
+ with open(file_or_path) as file_obj:
4207
+ return self._schema_from_json_file_object(file_obj)
4208
+
4209
+ def schema_to_json(
4210
+ self, schema_list: Sequence[SchemaField], destination: "PathType"
4211
+ ):
4212
+ """Takes a list of schema field objects.
4213
+
4214
+ Serializes the list of schema field objects as json to a file.
4215
+
4216
+ Destination is a file path or a file object.
4217
+ """
4218
+ json_schema_list = [f.to_api_repr() for f in schema_list]
4219
+
4220
+ if isinstance(destination, io.IOBase):
4221
+ return self._schema_to_json_file_object(json_schema_list, destination)
4222
+
4223
+ with open(destination, mode="w") as file_obj:
4224
+ return self._schema_to_json_file_object(json_schema_list, file_obj)
4225
+
4226
+ def __enter__(self):
4227
+ return self
4228
+
4229
+ def __exit__(self, exc_type, exc_value, traceback):
4230
+ self.close()
4231
+
4232
+
4233
+ # pylint: disable=unused-argument
4234
+ def _item_to_project(iterator, resource):
4235
+ """Convert a JSON project to the native object.
4236
+
4237
+ Args:
4238
+ iterator (google.api_core.page_iterator.Iterator): The iterator that is currently in use.
4239
+
4240
+ resource (Dict): An item to be converted to a project.
4241
+
4242
+ Returns:
4243
+ google.cloud.bigquery.client.Project: The next project in the page.
4244
+ """
4245
+ return Project.from_api_repr(resource)
4246
+
4247
+
4248
+ # pylint: enable=unused-argument
4249
+
4250
+
4251
+ def _item_to_dataset(iterator, resource):
4252
+ """Convert a JSON dataset to the native object.
4253
+
4254
+ Args:
4255
+ iterator (google.api_core.page_iterator.Iterator): The iterator that is currently in use.
4256
+
4257
+ resource (Dict): An item to be converted to a dataset.
4258
+
4259
+ Returns:
4260
+ google.cloud.bigquery.dataset.DatasetListItem: The next dataset in the page.
4261
+ """
4262
+ return DatasetListItem(resource)
4263
+
4264
+
4265
+ def _item_to_job(iterator, resource):
4266
+ """Convert a JSON job to the native object.
4267
+
4268
+ Args:
4269
+ iterator (google.api_core.page_iterator.Iterator): The iterator that is currently in use.
4270
+
4271
+ resource (Dict): An item to be converted to a job.
4272
+
4273
+ Returns:
4274
+ job instance: The next job in the page.
4275
+ """
4276
+ return iterator.client.job_from_resource(resource)
4277
+
4278
+
4279
+ def _item_to_model(iterator, resource):
4280
+ """Convert a JSON model to the native object.
4281
+
4282
+ Args:
4283
+ iterator (google.api_core.page_iterator.Iterator):
4284
+ The iterator that is currently in use.
4285
+ resource (Dict): An item to be converted to a model.
4286
+
4287
+ Returns:
4288
+ google.cloud.bigquery.model.Model: The next model in the page.
4289
+ """
4290
+ return Model.from_api_repr(resource)
4291
+
4292
+
4293
+ def _item_to_routine(iterator, resource):
4294
+ """Convert a JSON model to the native object.
4295
+
4296
+ Args:
4297
+ iterator (google.api_core.page_iterator.Iterator):
4298
+ The iterator that is currently in use.
4299
+ resource (Dict): An item to be converted to a routine.
4300
+
4301
+ Returns:
4302
+ google.cloud.bigquery.routine.Routine: The next routine in the page.
4303
+ """
4304
+ return Routine.from_api_repr(resource)
4305
+
4306
+
4307
+ def _item_to_table(iterator, resource):
4308
+ """Convert a JSON table to the native object.
4309
+
4310
+ Args:
4311
+ iterator (google.api_core.page_iterator.Iterator): The iterator that is currently in use.
4312
+
4313
+ resource (Dict): An item to be converted to a table.
4314
+
4315
+ Returns:
4316
+ google.cloud.bigquery.table.Table: The next table in the page.
4317
+ """
4318
+ return TableListItem(resource)
4319
+
4320
+
4321
+ def _extract_job_reference(job, project=None, location=None):
4322
+ """Extract fully-qualified job reference from a job-like object.
4323
+
4324
+ Args:
4325
+ job_id (Union[ \
4326
+ str, \
4327
+ google.cloud.bigquery.job.LoadJob, \
4328
+ google.cloud.bigquery.job.CopyJob, \
4329
+ google.cloud.bigquery.job.ExtractJob, \
4330
+ google.cloud.bigquery.job.QueryJob \
4331
+ ]): Job identifier.
4332
+ project (Optional[str]):
4333
+ Project where the job was run. Ignored if ``job_id`` is a job
4334
+ object.
4335
+ location (Optional[str]):
4336
+ Location where the job was run. Ignored if ``job_id`` is a job
4337
+ object.
4338
+
4339
+ Returns:
4340
+ Tuple[str, str, str]: ``(project, location, job_id)``
4341
+ """
4342
+ if hasattr(job, "job_id"):
4343
+ project = job.project
4344
+ job_id = job.job_id
4345
+ location = job.location
4346
+ else:
4347
+ job_id = job
4348
+
4349
+ return (project, location, job_id)
4350
+
4351
+
4352
+ def _check_mode(stream):
4353
+ """Check that a stream was opened in read-binary mode.
4354
+
4355
+ Args:
4356
+ stream (IO[bytes]): A bytes IO object open for reading.
4357
+
4358
+ Raises:
4359
+ ValueError:
4360
+ if the ``stream.mode`` is a valid attribute
4361
+ and is not among ``rb``, ``r+b`` or ``rb+``.
4362
+ """
4363
+ mode = getattr(stream, "mode", None)
4364
+
4365
+ if isinstance(stream, gzip.GzipFile):
4366
+ if mode != gzip.READ: # pytype: disable=module-attr
4367
+ raise ValueError(
4368
+ "Cannot upload gzip files opened in write mode: use "
4369
+ "gzip.GzipFile(filename, mode='rb')"
4370
+ )
4371
+ else:
4372
+ if mode is not None and mode not in ("rb", "r+b", "rb+"):
4373
+ raise ValueError(
4374
+ "Cannot upload files opened in text mode: use "
4375
+ "open(filename, mode='rb') or open(filename, mode='r+b')"
4376
+ )
4377
+
4378
+
4379
+ def _get_upload_headers(user_agent):
4380
+ """Get the headers for an upload request.
4381
+
4382
+ Args:
4383
+ user_agent (str): The user-agent for requests.
4384
+
4385
+ Returns:
4386
+ Dict: The headers to be used for the request.
4387
+ """
4388
+ return {
4389
+ "Accept": "application/json",
4390
+ "Accept-Encoding": "gzip, deflate",
4391
+ "User-Agent": user_agent,
4392
+ "content-type": "application/json; charset=UTF-8",
4393
+ }
4394
+
4395
+
4396
+ def _add_server_timeout_header(headers: Optional[Dict[str, str]], kwargs):
4397
+ timeout = kwargs.get("timeout")
4398
+ if timeout is not None:
4399
+ if headers is None:
4400
+ headers = {}
4401
+ headers[TIMEOUT_HEADER] = str(timeout)
4402
+
4403
+ if headers:
4404
+ kwargs["headers"] = headers
4405
+
4406
+ return kwargs