diff --git a/.kokoro/presubmit/presubmit.cfg b/.kokoro/presubmit/presubmit.cfg
index b158096f0..8f43917d9 100644
--- a/.kokoro/presubmit/presubmit.cfg
+++ b/.kokoro/presubmit/presubmit.cfg
@@ -1,7 +1 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Disable system tests.
-env_vars: {
- key: "RUN_SYSTEM_TESTS"
- value: "false"
-}
+# Format: //devtools/kokoro/config/proto/build.proto
\ No newline at end of file
diff --git a/.kokoro/presubmit/system-2.7.cfg b/.kokoro/presubmit/system-2.7.cfg
deleted file mode 100644
index 3b6523a19..000000000
--- a/.kokoro/presubmit/system-2.7.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Only run this nox session.
-env_vars: {
- key: "NOX_SESSION"
- value: "system-2.7"
-}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.6/common.cfg b/.kokoro/samples/python3.6/common.cfg
index a56768eae..f3b930960 100644
--- a/.kokoro/samples/python3.6/common.cfg
+++ b/.kokoro/samples/python3.6/common.cfg
@@ -13,6 +13,12 @@ env_vars: {
value: "py-3.6"
}
+# Declare build specific Cloud project.
+env_vars: {
+ key: "BUILD_SPECIFIC_GCLOUD_PROJECT"
+ value: "python-docs-samples-tests-py36"
+}
+
env_vars: {
key: "TRAMPOLINE_BUILD_FILE"
value: "github/python-bigquery/.kokoro/test-samples.sh"
diff --git a/.kokoro/samples/python3.7/common.cfg b/.kokoro/samples/python3.7/common.cfg
index c93747180..fc0654565 100644
--- a/.kokoro/samples/python3.7/common.cfg
+++ b/.kokoro/samples/python3.7/common.cfg
@@ -13,6 +13,12 @@ env_vars: {
value: "py-3.7"
}
+# Declare build specific Cloud project.
+env_vars: {
+ key: "BUILD_SPECIFIC_GCLOUD_PROJECT"
+ value: "python-docs-samples-tests-py37"
+}
+
env_vars: {
key: "TRAMPOLINE_BUILD_FILE"
value: "github/python-bigquery/.kokoro/test-samples.sh"
diff --git a/.kokoro/samples/python3.8/common.cfg b/.kokoro/samples/python3.8/common.cfg
index 9808f15e3..2b0bf59b3 100644
--- a/.kokoro/samples/python3.8/common.cfg
+++ b/.kokoro/samples/python3.8/common.cfg
@@ -13,6 +13,12 @@ env_vars: {
value: "py-3.8"
}
+# Declare build specific Cloud project.
+env_vars: {
+ key: "BUILD_SPECIFIC_GCLOUD_PROJECT"
+ value: "python-docs-samples-tests-py38"
+}
+
env_vars: {
key: "TRAMPOLINE_BUILD_FILE"
value: "github/python-bigquery/.kokoro/test-samples.sh"
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 3366287d6..b3b802b49 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -80,25 +80,6 @@ We use `nox `__ to instrument our tests.
.. nox: https://pypi.org/project/nox/
-Note on Editable Installs / Develop Mode
-========================================
-
-- As mentioned previously, using ``setuptools`` in `develop mode`_
- or a ``pip`` `editable install`_ is not possible with this
- library. This is because this library uses `namespace packages`_.
- For context see `Issue #2316`_ and the relevant `PyPA issue`_.
-
- Since ``editable`` / ``develop`` mode can't be used, packages
- need to be installed directly. Hence your changes to the source
- tree don't get incorporated into the **already installed**
- package.
-
-.. _namespace packages: https://www.python.org/dev/peps/pep-0420/
-.. _Issue #2316: https://github.com/GoogleCloudPlatform/google-cloud-python/issues/2316
-.. _PyPA issue: https://github.com/pypa/packaging-problems/issues/12
-.. _develop mode: https://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode
-.. _editable install: https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs
-
*****************************************
I'm getting weird errors... Can you help?
*****************************************
diff --git a/README.rst b/README.rst
index c6bc17834..c7d50d729 100644
--- a/README.rst
+++ b/README.rst
@@ -52,11 +52,14 @@ dependencies.
Supported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^
-Python >= 3.5
+Python >= 3.6
-Deprecated Python Versions
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-Python == 2.7. Python 2.7 support will be removed on January 1, 2020.
+Unsupported Python Versions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Python == 2.7, Python == 3.5.
+
+The last version of this library compatible with Python 2.7 and 3.5 is
+`google-cloud-bigquery==1.28.0`.
Mac/Linux
diff --git a/UPGRADING.md b/UPGRADING.md
new file mode 100644
index 000000000..a4ba0efd2
--- /dev/null
+++ b/UPGRADING.md
@@ -0,0 +1,59 @@
+
+
+
+# 2.0.0 Migration Guide
+
+The 2.0 release of the `google-cloud-bigquery` client drops support for Python
+versions below 3.6. The client surface itself has not changed, but the 1.x series
+will not be receiving any more feature updates or bug fixes. You are thus
+encouraged to upgrade to the 2.x series.
+
+If you experience issues or have questions, please file an
+[issue](https://github.com/googleapis/python-bigquery/issues).
+
+
+## Supported Python Versions
+
+> **WARNING**: Breaking change
+
+The 2.0.0 release requires Python 3.6+.
+
+
+## Supported BigQuery Storage Clients
+
+The 2.0.0 release requires BigQuery Storage `>= 2.0.0`, which dropped support
+for `v1beta1` and `v1beta2` versions of the BigQuery Storage API. If you want to
+use a BigQuery Storage client, it must be the one supporting the `v1` API version.
+
+
+## Changed GAPIC Enums Path
+
+> **WARNING**: Breaking change
+
+Generated GAPIC enum types have been moved under `types`. Import paths need to be
+adjusted.
+
+**Before:**
+```py
+from google.cloud.bigquery_v2.gapic import enums
+
+distance_type = enums.Model.DistanceType.COSINE
+```
+
+**After:**
+```py
+from google.cloud.bigquery_v2 import types
+
+distance_type = types.Model.DistanceType.COSINE
+```
\ No newline at end of file
diff --git a/docs/UPGRADING.md b/docs/UPGRADING.md
new file mode 120000
index 000000000..01097c8c0
--- /dev/null
+++ b/docs/UPGRADING.md
@@ -0,0 +1 @@
+../UPGRADING.md
\ No newline at end of file
diff --git a/docs/bigquery_v2/services.rst b/docs/bigquery_v2/services.rst
new file mode 100644
index 000000000..65fbb438c
--- /dev/null
+++ b/docs/bigquery_v2/services.rst
@@ -0,0 +1,6 @@
+Services for Google Cloud Bigquery v2 API
+=========================================
+
+.. automodule:: google.cloud.bigquery_v2.services.model_service
+ :members:
+ :inherited-members:
diff --git a/docs/bigquery_v2/types.rst b/docs/bigquery_v2/types.rst
new file mode 100644
index 000000000..f43809958
--- /dev/null
+++ b/docs/bigquery_v2/types.rst
@@ -0,0 +1,5 @@
+Types for Google Cloud Bigquery v2 API
+======================================
+
+.. automodule:: google.cloud.bigquery_v2.types
+ :members:
diff --git a/docs/conf.py b/docs/conf.py
index b38bdd1ff..ee59f3492 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -100,6 +100,7 @@
"samples/AUTHORING_GUIDE.md",
"samples/CONTRIBUTING.md",
"samples/snippets/README.rst",
+ "bigquery_v2/services.rst", # generated by the code generator
]
# The reST default role (used for this markup: `text`) to use for all
diff --git a/docs/gapic/v2/enums.rst b/docs/gapic/v2/enums.rst
deleted file mode 100644
index 0e0f05ada..000000000
--- a/docs/gapic/v2/enums.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Enums for BigQuery API Client
-=============================
-
-.. autoclass:: google.cloud.bigquery_v2.gapic.enums.Model
- :members:
-
-.. autoclass:: google.cloud.bigquery_v2.gapic.enums.StandardSqlDataType
- :members:
diff --git a/docs/gapic/v2/types.rst b/docs/gapic/v2/types.rst
deleted file mode 100644
index 99b954eca..000000000
--- a/docs/gapic/v2/types.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Types for BigQuery API Client
-=============================
-
-.. automodule:: google.cloud.bigquery_v2.types
- :members:
- :noindex:
\ No newline at end of file
diff --git a/docs/index.rst b/docs/index.rst
index 62a82e0e9..3f8ba2304 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -27,6 +27,16 @@ API Reference
reference
dbapi
+Migration Guide
+---------------
+
+See the guide below for instructions on migrating to the 2.x release of this library.
+
+.. toctree::
+ :maxdepth: 2
+
+ UPGRADING
+
Changelog
---------
diff --git a/docs/reference.rst b/docs/reference.rst
index 981059de5..21dd8e43d 100644
--- a/docs/reference.rst
+++ b/docs/reference.rst
@@ -182,6 +182,7 @@ Encryption Configuration
encryption_configuration.EncryptionConfiguration
+
Additional Types
================
@@ -190,5 +191,4 @@ Protocol buffer classes for working with the Models API.
.. toctree::
:maxdepth: 2
- gapic/v2/enums
- gapic/v2/types
+ bigquery_v2/types
diff --git a/google/cloud/bigquery/_pandas_helpers.py b/google/cloud/bigquery/_pandas_helpers.py
index 953b7d0fe..57c8f95f6 100644
--- a/google/cloud/bigquery/_pandas_helpers.py
+++ b/google/cloud/bigquery/_pandas_helpers.py
@@ -22,11 +22,6 @@
import six
from six.moves import queue
-try:
- from google.cloud import bigquery_storage_v1
-except ImportError: # pragma: NO COVER
- bigquery_storage_v1 = None
-
try:
import pandas
except ImportError: # pragma: NO COVER
@@ -287,14 +282,6 @@ def dataframe_to_bq_schema(dataframe, bq_schema):
"""
if bq_schema:
bq_schema = schema._to_schema_fields(bq_schema)
- if six.PY2:
- for field in bq_schema:
- if field.field_type in schema._STRUCT_TYPES:
- raise ValueError(
- "Uploading dataframes with struct (record) column types "
- "is not supported under Python2. See: "
- "https://github.com/googleapis/python-bigquery/issues/21"
- )
bq_schema_index = {field.name: field for field in bq_schema}
bq_schema_unused = set(bq_schema_index.keys())
else:
@@ -578,19 +565,7 @@ def _bqstorage_page_to_dataframe(column_names, dtypes, page):
def _download_table_bqstorage_stream(
download_state, bqstorage_client, session, stream, worker_queue, page_to_item
):
- # Passing a BQ Storage client in implies that the BigQuery Storage library
- # is available and can be imported.
- from google.cloud import bigquery_storage_v1beta1
-
- # We want to preserve comaptibility with the v1beta1 BQ Storage clients,
- # thus adjust constructing the rowstream if needed.
- # The assumption is that the caller provides a BQ Storage `session` that is
- # compatible with the version of the BQ Storage client passed in.
- if isinstance(bqstorage_client, bigquery_storage_v1beta1.BigQueryStorageClient):
- position = bigquery_storage_v1beta1.types.StreamPosition(stream=stream)
- rowstream = bqstorage_client.read_rows(position).rows(session)
- else:
- rowstream = bqstorage_client.read_rows(stream.name).rows(session)
+ rowstream = bqstorage_client.read_rows(stream.name).rows(session)
for page in rowstream.pages:
if download_state.done:
@@ -625,8 +600,7 @@ def _download_table_bqstorage(
# Passing a BQ Storage client in implies that the BigQuery Storage library
# is available and can be imported.
- from google.cloud import bigquery_storage_v1
- from google.cloud import bigquery_storage_v1beta1
+ from google.cloud import bigquery_storage
if "$" in table.table_id:
raise ValueError(
@@ -637,41 +611,18 @@ def _download_table_bqstorage(
requested_streams = 1 if preserve_order else 0
- # We want to preserve comaptibility with the v1beta1 BQ Storage clients,
- # thus adjust the session creation if needed.
- if isinstance(bqstorage_client, bigquery_storage_v1beta1.BigQueryStorageClient):
- warnings.warn(
- "Support for BigQuery Storage v1beta1 clients is deprecated, please "
- "consider upgrading the client to BigQuery Storage v1 stable version.",
- category=DeprecationWarning,
- )
- read_options = bigquery_storage_v1beta1.types.TableReadOptions()
-
- if selected_fields is not None:
- for field in selected_fields:
- read_options.selected_fields.append(field.name)
-
- session = bqstorage_client.create_read_session(
- table.to_bqstorage(v1beta1=True),
- "projects/{}".format(project_id),
- format_=bigquery_storage_v1beta1.enums.DataFormat.ARROW,
- read_options=read_options,
- requested_streams=requested_streams,
- )
- else:
- requested_session = bigquery_storage_v1.types.ReadSession(
- table=table.to_bqstorage(),
- data_format=bigquery_storage_v1.enums.DataFormat.ARROW,
- )
- if selected_fields is not None:
- for field in selected_fields:
- requested_session.read_options.selected_fields.append(field.name)
-
- session = bqstorage_client.create_read_session(
- parent="projects/{}".format(project_id),
- read_session=requested_session,
- max_stream_count=requested_streams,
- )
+ requested_session = bigquery_storage.types.ReadSession(
+ table=table.to_bqstorage(), data_format=bigquery_storage.types.DataFormat.ARROW
+ )
+ if selected_fields is not None:
+ for field in selected_fields:
+ requested_session.read_options.selected_fields.append(field.name)
+
+ session = bqstorage_client.create_read_session(
+ parent="projects/{}".format(project_id),
+ read_session=requested_session,
+ max_stream_count=requested_streams,
+ )
_LOGGER.debug(
"Started reading table '{}.{}.{}' with BQ Storage API session '{}'.".format(
diff --git a/google/cloud/bigquery/client.py b/google/cloud/bigquery/client.py
index d2aa45999..fcb18385d 100644
--- a/google/cloud/bigquery/client.py
+++ b/google/cloud/bigquery/client.py
@@ -17,11 +17,7 @@
from __future__ import absolute_import
from __future__ import division
-try:
- from collections import abc as collections_abc
-except ImportError: # Python 2.7
- import collections as collections_abc
-
+from collections import abc as collections_abc
import copy
import functools
import gzip
@@ -435,11 +431,11 @@ def _create_bqstorage_client(self):
warning and return ``None``.
Returns:
- Optional[google.cloud.bigquery_storage_v1.BigQueryReadClient]:
+ Optional[google.cloud.bigquery_storage.BigQueryReadClient]:
A BigQuery Storage API client.
"""
try:
- from google.cloud import bigquery_storage_v1
+ from google.cloud import bigquery_storage
except ImportError:
warnings.warn(
"Cannot create BigQuery Storage client, the dependency "
@@ -447,7 +443,7 @@ def _create_bqstorage_client(self):
)
return None
- return bigquery_storage_v1.BigQueryReadClient(credentials=self._credentials)
+ return bigquery_storage.BigQueryReadClient(credentials=self._credentials)
def create_dataset(
self, dataset, exists_ok=False, retry=DEFAULT_RETRY, timeout=None
diff --git a/google/cloud/bigquery/dbapi/_helpers.py b/google/cloud/bigquery/dbapi/_helpers.py
index 1bcf45f31..fdf4e17c3 100644
--- a/google/cloud/bigquery/dbapi/_helpers.py
+++ b/google/cloud/bigquery/dbapi/_helpers.py
@@ -12,11 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-try:
- from collections import abc as collections_abc
-except ImportError: # Python 2.7
- import collections as collections_abc
+from collections import abc as collections_abc
import datetime
import decimal
import functools
diff --git a/google/cloud/bigquery/dbapi/connection.py b/google/cloud/bigquery/dbapi/connection.py
index 464b0fd06..300c77dc9 100644
--- a/google/cloud/bigquery/dbapi/connection.py
+++ b/google/cloud/bigquery/dbapi/connection.py
@@ -73,7 +73,7 @@ def close(self):
if self._owns_bqstorage_client:
# There is no close() on the BQ Storage client itself.
- self._bqstorage_client.transport.channel.close()
+ self._bqstorage_client._transport.grpc_channel.close()
for cursor_ in self._cursors_created:
cursor_.close()
diff --git a/google/cloud/bigquery/dbapi/cursor.py b/google/cloud/bigquery/dbapi/cursor.py
index 7a10637f0..63264e9ab 100644
--- a/google/cloud/bigquery/dbapi/cursor.py
+++ b/google/cloud/bigquery/dbapi/cursor.py
@@ -15,14 +15,8 @@
"""Cursor for the Google BigQuery DB-API."""
import collections
+from collections import abc as collections_abc
import copy
-import warnings
-
-try:
- from collections import abc as collections_abc
-except ImportError: # Python 2.7
- import collections as collections_abc
-
import logging
import six
@@ -267,54 +261,27 @@ def _bqstorage_fetch(self, bqstorage_client):
A sequence of rows, represented as dictionaries.
"""
# Hitting this code path with a BQ Storage client instance implies that
- # bigquery_storage_v1* can indeed be imported here without errors.
- from google.cloud import bigquery_storage_v1
- from google.cloud import bigquery_storage_v1beta1
+ # bigquery_storage can indeed be imported here without errors.
+ from google.cloud import bigquery_storage
table_reference = self._query_job.destination
- is_v1beta1_client = isinstance(
- bqstorage_client, bigquery_storage_v1beta1.BigQueryStorageClient
+ requested_session = bigquery_storage.types.ReadSession(
+ table=table_reference.to_bqstorage(),
+ data_format=bigquery_storage.types.DataFormat.ARROW,
+ )
+ read_session = bqstorage_client.create_read_session(
+ parent="projects/{}".format(table_reference.project),
+ read_session=requested_session,
+ # a single stream only, as DB API is not well-suited for multithreading
+ max_stream_count=1,
)
-
- # We want to preserve compatibility with the v1beta1 BQ Storage clients,
- # thus adjust the session creation if needed.
- if is_v1beta1_client:
- warnings.warn(
- "Support for BigQuery Storage v1beta1 clients is deprecated, please "
- "consider upgrading the client to BigQuery Storage v1 stable version.",
- category=DeprecationWarning,
- )
- read_session = bqstorage_client.create_read_session(
- table_reference.to_bqstorage(v1beta1=True),
- "projects/{}".format(table_reference.project),
- # a single stream only, as DB API is not well-suited for multithreading
- requested_streams=1,
- format_=bigquery_storage_v1beta1.enums.DataFormat.ARROW,
- )
- else:
- requested_session = bigquery_storage_v1.types.ReadSession(
- table=table_reference.to_bqstorage(),
- data_format=bigquery_storage_v1.enums.DataFormat.ARROW,
- )
- read_session = bqstorage_client.create_read_session(
- parent="projects/{}".format(table_reference.project),
- read_session=requested_session,
- # a single stream only, as DB API is not well-suited for multithreading
- max_stream_count=1,
- )
if not read_session.streams:
return iter([]) # empty table, nothing to read
- if is_v1beta1_client:
- read_position = bigquery_storage_v1beta1.types.StreamPosition(
- stream=read_session.streams[0],
- )
- read_rows_stream = bqstorage_client.read_rows(read_position)
- else:
- stream_name = read_session.streams[0].name
- read_rows_stream = bqstorage_client.read_rows(stream_name)
+ stream_name = read_session.streams[0].name
+ read_rows_stream = bqstorage_client.read_rows(stream_name)
rows_iterable = read_rows_stream.rows(read_session)
return rows_iterable
diff --git a/google/cloud/bigquery/enums.py b/google/cloud/bigquery/enums.py
index 29fe543f6..3247372e3 100644
--- a/google/cloud/bigquery/enums.py
+++ b/google/cloud/bigquery/enums.py
@@ -17,7 +17,7 @@
import enum
import six
-from google.cloud.bigquery_v2.gapic import enums as gapic_enums
+from google.cloud.bigquery_v2 import types as gapic_types
_SQL_SCALAR_TYPES = frozenset(
@@ -46,13 +46,13 @@ def _make_sql_scalars_enum():
"StandardSqlDataTypes",
(
(member.name, member.value)
- for member in gapic_enums.StandardSqlDataType.TypeKind
+ for member in gapic_types.StandardSqlDataType.TypeKind
if member.name in _SQL_SCALAR_TYPES
),
)
# make sure the docstring for the new enum is also correct
- orig_doc = gapic_enums.StandardSqlDataType.TypeKind.__doc__
+ orig_doc = gapic_types.StandardSqlDataType.TypeKind.__doc__
skip_pattern = re.compile(
"|".join(_SQL_NONSCALAR_TYPES)
+ "|because a JSON object" # the second description line of STRUCT member
diff --git a/google/cloud/bigquery/magics/magics.py b/google/cloud/bigquery/magics/magics.py
index 4842c7680..22175ee45 100644
--- a/google/cloud/bigquery/magics/magics.py
+++ b/google/cloud/bigquery/magics/magics.py
@@ -637,7 +637,7 @@ def _make_bqstorage_client(use_bqstorage_api, credentials):
return None
try:
- from google.cloud import bigquery_storage_v1
+ from google.cloud import bigquery_storage
except ImportError as err:
customized_error = ImportError(
"The default BigQuery Storage API client cannot be used, install "
@@ -655,7 +655,7 @@ def _make_bqstorage_client(use_bqstorage_api, credentials):
)
six.raise_from(customized_error, err)
- return bigquery_storage_v1.BigQueryReadClient(
+ return bigquery_storage.BigQueryReadClient(
credentials=credentials,
client_info=gapic_client_info.ClientInfo(user_agent=IPYTHON_USER_AGENT),
)
@@ -670,10 +670,10 @@ def _close_transports(client, bqstorage_client):
Args:
client (:class:`~google.cloud.bigquery.client.Client`):
bqstorage_client
- (Optional[:class:`~google.cloud.bigquery_storage_v1.BigQueryReadClient`]):
+ (Optional[:class:`~google.cloud.bigquery_storage.BigQueryReadClient`]):
A client for the BigQuery Storage API.
"""
client.close()
if bqstorage_client is not None:
- bqstorage_client.transport.channel.close()
+ bqstorage_client._transport.grpc_channel.close()
diff --git a/google/cloud/bigquery/model.py b/google/cloud/bigquery/model.py
index d3fe8a937..092d98c2e 100644
--- a/google/cloud/bigquery/model.py
+++ b/google/cloud/bigquery/model.py
@@ -55,7 +55,7 @@ class Model(object):
def __init__(self, model_ref):
# Use _proto on read-only properties to use it's built-in type
# conversion.
- self._proto = types.Model()
+ self._proto = types.Model()._pb
# Use _properties on read-write properties to match the REST API
# semantics. The BigQuery API makes a distinction between an unset
@@ -151,13 +151,13 @@ def modified(self):
@property
def model_type(self):
- """google.cloud.bigquery_v2.gapic.enums.Model.ModelType: Type of the
+ """google.cloud.bigquery_v2.types.Model.ModelType: Type of the
model resource.
Read-only.
The value is one of elements of the
- :class:`~google.cloud.bigquery_v2.gapic.enums.Model.ModelType`
+ :class:`~google.cloud.bigquery_v2.types.Model.ModelType`
enumeration.
"""
return self._proto.model_type
@@ -306,7 +306,7 @@ def from_api_repr(cls, resource):
training_run["startTime"] = datetime_helpers.to_rfc3339(start_time)
this._proto = json_format.ParseDict(
- resource, types.Model(), ignore_unknown_fields=True
+ resource, types.Model()._pb, ignore_unknown_fields=True
)
return this
@@ -326,7 +326,7 @@ class ModelReference(object):
"""
def __init__(self):
- self._proto = types.ModelReference()
+ self._proto = types.ModelReference()._pb
self._properties = {}
@property
@@ -370,8 +370,9 @@ def from_api_repr(cls, resource):
# field values.
ref._properties = resource
ref._proto = json_format.ParseDict(
- resource, types.ModelReference(), ignore_unknown_fields=True
+ resource, types.ModelReference()._pb, ignore_unknown_fields=True
)
+
return ref
@classmethod
diff --git a/google/cloud/bigquery/routine.py b/google/cloud/bigquery/routine.py
index 03423c01b..6a0ed9fb0 100644
--- a/google/cloud/bigquery/routine.py
+++ b/google/cloud/bigquery/routine.py
@@ -189,14 +189,17 @@ def return_type(self):
resource = self._properties.get(self._PROPERTY_TO_API_FIELD["return_type"])
if not resource:
return resource
+
output = google.cloud.bigquery_v2.types.StandardSqlDataType()
- output = json_format.ParseDict(resource, output, ignore_unknown_fields=True)
- return output
+ raw_protobuf = json_format.ParseDict(
+ resource, output._pb, ignore_unknown_fields=True
+ )
+ return type(output).wrap(raw_protobuf)
@return_type.setter
def return_type(self, value):
if value:
- resource = json_format.MessageToDict(value)
+ resource = json_format.MessageToDict(value._pb)
else:
resource = None
self._properties[self._PROPERTY_TO_API_FIELD["return_type"]] = resource
@@ -357,14 +360,17 @@ def data_type(self):
resource = self._properties.get(self._PROPERTY_TO_API_FIELD["data_type"])
if not resource:
return resource
+
output = google.cloud.bigquery_v2.types.StandardSqlDataType()
- output = json_format.ParseDict(resource, output, ignore_unknown_fields=True)
- return output
+ raw_protobuf = json_format.ParseDict(
+ resource, output._pb, ignore_unknown_fields=True
+ )
+ return type(output).wrap(raw_protobuf)
@data_type.setter
def data_type(self, value):
if value:
- resource = json_format.MessageToDict(value)
+ resource = json_format.MessageToDict(value._pb)
else:
resource = None
self._properties[self._PROPERTY_TO_API_FIELD["data_type"]] = resource
diff --git a/google/cloud/bigquery/schema.py b/google/cloud/bigquery/schema.py
index c1b2588be..8ae0a3a85 100644
--- a/google/cloud/bigquery/schema.py
+++ b/google/cloud/bigquery/schema.py
@@ -25,22 +25,22 @@
# https://cloud.google.com/bigquery/data-types#legacy_sql_data_types
# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types
LEGACY_TO_STANDARD_TYPES = {
- "STRING": types.StandardSqlDataType.STRING,
- "BYTES": types.StandardSqlDataType.BYTES,
- "INTEGER": types.StandardSqlDataType.INT64,
- "INT64": types.StandardSqlDataType.INT64,
- "FLOAT": types.StandardSqlDataType.FLOAT64,
- "FLOAT64": types.StandardSqlDataType.FLOAT64,
- "NUMERIC": types.StandardSqlDataType.NUMERIC,
- "BOOLEAN": types.StandardSqlDataType.BOOL,
- "BOOL": types.StandardSqlDataType.BOOL,
- "GEOGRAPHY": types.StandardSqlDataType.GEOGRAPHY,
- "RECORD": types.StandardSqlDataType.STRUCT,
- "STRUCT": types.StandardSqlDataType.STRUCT,
- "TIMESTAMP": types.StandardSqlDataType.TIMESTAMP,
- "DATE": types.StandardSqlDataType.DATE,
- "TIME": types.StandardSqlDataType.TIME,
- "DATETIME": types.StandardSqlDataType.DATETIME,
+ "STRING": types.StandardSqlDataType.TypeKind.STRING,
+ "BYTES": types.StandardSqlDataType.TypeKind.BYTES,
+ "INTEGER": types.StandardSqlDataType.TypeKind.INT64,
+ "INT64": types.StandardSqlDataType.TypeKind.INT64,
+ "FLOAT": types.StandardSqlDataType.TypeKind.FLOAT64,
+ "FLOAT64": types.StandardSqlDataType.TypeKind.FLOAT64,
+ "NUMERIC": types.StandardSqlDataType.TypeKind.NUMERIC,
+ "BOOLEAN": types.StandardSqlDataType.TypeKind.BOOL,
+ "BOOL": types.StandardSqlDataType.TypeKind.BOOL,
+ "GEOGRAPHY": types.StandardSqlDataType.TypeKind.GEOGRAPHY,
+ "RECORD": types.StandardSqlDataType.TypeKind.STRUCT,
+ "STRUCT": types.StandardSqlDataType.TypeKind.STRUCT,
+ "TIMESTAMP": types.StandardSqlDataType.TypeKind.TIMESTAMP,
+ "DATE": types.StandardSqlDataType.TypeKind.DATE,
+ "TIME": types.StandardSqlDataType.TypeKind.TIME,
+ "DATETIME": types.StandardSqlDataType.TypeKind.DATETIME,
# no direct conversion from ARRAY, the latter is represented by mode="REPEATED"
}
"""String names of the legacy SQL types to integer codes of Standard SQL types."""
@@ -209,26 +209,34 @@ def to_standard_sql(self):
sql_type = types.StandardSqlDataType()
if self.mode == "REPEATED":
- sql_type.type_kind = types.StandardSqlDataType.ARRAY
+ sql_type.type_kind = types.StandardSqlDataType.TypeKind.ARRAY
else:
sql_type.type_kind = LEGACY_TO_STANDARD_TYPES.get(
- self.field_type, types.StandardSqlDataType.TYPE_KIND_UNSPECIFIED
+ self.field_type,
+ types.StandardSqlDataType.TypeKind.TYPE_KIND_UNSPECIFIED,
)
- if sql_type.type_kind == types.StandardSqlDataType.ARRAY: # noqa: E721
+ if sql_type.type_kind == types.StandardSqlDataType.TypeKind.ARRAY: # noqa: E721
array_element_type = LEGACY_TO_STANDARD_TYPES.get(
- self.field_type, types.StandardSqlDataType.TYPE_KIND_UNSPECIFIED
+ self.field_type,
+ types.StandardSqlDataType.TypeKind.TYPE_KIND_UNSPECIFIED,
)
sql_type.array_element_type.type_kind = array_element_type
# ARRAY cannot directly contain other arrays, only scalar types and STRUCTs
# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#array-type
- if array_element_type == types.StandardSqlDataType.STRUCT: # noqa: E721
+ if (
+ array_element_type
+ == types.StandardSqlDataType.TypeKind.STRUCT # noqa: E721
+ ):
sql_type.array_element_type.struct_type.fields.extend(
field.to_standard_sql() for field in self.fields
)
- elif sql_type.type_kind == types.StandardSqlDataType.STRUCT: # noqa: E721
+ elif (
+ sql_type.type_kind
+ == types.StandardSqlDataType.TypeKind.STRUCT # noqa: E721
+ ):
sql_type.struct_type.fields.extend(
field.to_standard_sql() for field in self.fields
)
diff --git a/google/cloud/bigquery/table.py b/google/cloud/bigquery/table.py
index d9e5f7773..902a7040a 100644
--- a/google/cloud/bigquery/table.py
+++ b/google/cloud/bigquery/table.py
@@ -26,12 +26,6 @@
import six
-try:
- # Needed for the to_bqstorage() method.
- from google.cloud import bigquery_storage_v1beta1
-except ImportError: # pragma: NO COVER
- bigquery_storage_v1beta1 = None
-
try:
import pandas
except ImportError: # pragma: NO COVER
@@ -228,7 +222,7 @@ def to_api_repr(self):
"tableId": self._table_id,
}
- def to_bqstorage(self, v1beta1=False):
+ def to_bqstorage(self):
"""Construct a BigQuery Storage API representation of this table.
Install the ``google-cloud-bigquery-storage`` package to use this
@@ -237,41 +231,21 @@ def to_bqstorage(self, v1beta1=False):
If the ``table_id`` contains a partition identifier (e.g.
``my_table$201812``) or a snapshot identifier (e.g.
``mytable@1234567890``), it is ignored. Use
- :class:`google.cloud.bigquery_storage_v1.types.ReadSession.TableReadOptions`
+ :class:`google.cloud.bigquery_storage.types.ReadSession.TableReadOptions`
to filter rows by partition. Use
- :class:`google.cloud.bigquery_storage_v1.types.ReadSession.TableModifiers`
+ :class:`google.cloud.bigquery_storage.types.ReadSession.TableModifiers`
to select a specific snapshot to read from.
- Args:
- v1beta1 (Optiona[bool]):
- If :data:`True`, return representation compatible with BigQuery
- Storage ``v1beta1`` version. Defaults to :data:`False`.
-
Returns:
- Union[str, google.cloud.bigquery_storage_v1beta1.types.TableReference:]:
- A reference to this table in the BigQuery Storage API.
-
- Raises:
- ValueError:
- If ``v1beta1`` compatibility is requested, but the
- :mod:`google.cloud.bigquery_storage_v1beta1` module cannot be imported.
+ str: A reference to this table in the BigQuery Storage API.
"""
- if v1beta1 and bigquery_storage_v1beta1 is None:
- raise ValueError(_NO_BQSTORAGE_ERROR)
table_id, _, _ = self._table_id.partition("@")
table_id, _, _ = table_id.partition("$")
- if v1beta1:
- table_ref = bigquery_storage_v1beta1.types.TableReference(
- project_id=self._project,
- dataset_id=self._dataset_id,
- table_id=table_id,
- )
- else:
- table_ref = "projects/{}/datasets/{}/tables/{}".format(
- self._project, self._dataset_id, table_id,
- )
+ table_ref = "projects/{}/datasets/{}/tables/{}".format(
+ self._project, self._dataset_id, table_id,
+ )
return table_ref
@@ -876,19 +850,13 @@ def to_api_repr(self):
"""
return copy.deepcopy(self._properties)
- def to_bqstorage(self, v1beta1=False):
+ def to_bqstorage(self):
"""Construct a BigQuery Storage API representation of this table.
- Args:
- v1beta1 (Optiona[bool]):
- If :data:`True`, return representation compatible with BigQuery
- Storage ``v1beta1`` version. Defaults to :data:`False`.
-
Returns:
- Union[str, google.cloud.bigquery_storage_v1beta1.types.TableReference:]:
- A reference to this table in the BigQuery Storage API.
+ str: A reference to this table in the BigQuery Storage API.
"""
- return self.reference.to_bqstorage(v1beta1=v1beta1)
+ return self.reference.to_bqstorage()
def _build_resource(self, filter_fields):
"""Generate a resource for ``update``."""
@@ -1096,19 +1064,13 @@ def from_string(cls, full_table_id):
{"tableReference": TableReference.from_string(full_table_id).to_api_repr()}
)
- def to_bqstorage(self, v1beta1=False):
+ def to_bqstorage(self):
"""Construct a BigQuery Storage API representation of this table.
- Args:
- v1beta1 (Optiona[bool]):
- If :data:`True`, return representation compatible with BigQuery
- Storage ``v1beta1`` version. Defaults to :data:`False`.
-
Returns:
- Union[str, google.cloud.bigquery_storage_v1beta1.types.TableReference:]:
- A reference to this table in the BigQuery Storage API.
+ str: A reference to this table in the BigQuery Storage API.
"""
- return self.reference.to_bqstorage(v1beta1=v1beta1)
+ return self.reference.to_bqstorage()
def _row_from_mapping(mapping, schema):
@@ -1559,7 +1521,7 @@ def to_arrow(
progress_bar.close()
finally:
if owns_bqstorage_client:
- bqstorage_client.transport.channel.close()
+ bqstorage_client._transport.grpc_channel.close()
if record_batches:
return pyarrow.Table.from_batches(record_batches)
@@ -1731,28 +1693,22 @@ def to_dataframe(
# When converting timestamp values to nanosecond precision, the result
# can be out of pyarrow bounds. To avoid the error when converting to
# Pandas, we set the timestamp_as_object parameter to True, if necessary.
- #
- # NOTE: Python 3+ only, as timestamp_as_object parameter is only supported
- # in pyarrow>=1.0, but the latter is not compatible with Python 2.
- if six.PY2:
- extra_kwargs = {}
+ types_to_check = {
+ pyarrow.timestamp("us"),
+ pyarrow.timestamp("us", tz=pytz.UTC),
+ }
+
+ for column in record_batch:
+ if column.type in types_to_check:
+ try:
+ column.cast("timestamp[ns]")
+ except pyarrow.lib.ArrowInvalid:
+ timestamp_as_object = True
+ break
else:
- types_to_check = {
- pyarrow.timestamp("us"),
- pyarrow.timestamp("us", tz=pytz.UTC),
- }
-
- for column in record_batch:
- if column.type in types_to_check:
- try:
- column.cast("timestamp[ns]")
- except pyarrow.lib.ArrowInvalid:
- timestamp_as_object = True
- break
- else:
- timestamp_as_object = False
-
- extra_kwargs = {"timestamp_as_object": timestamp_as_object}
+ timestamp_as_object = False
+
+ extra_kwargs = {"timestamp_as_object": timestamp_as_object}
df = record_batch.to_pandas(date_as_object=date_as_object, **extra_kwargs)
diff --git a/google/cloud/bigquery_v2/__init__.py b/google/cloud/bigquery_v2/__init__.py
index e58221432..c1989c3b0 100644
--- a/google/cloud/bigquery_v2/__init__.py
+++ b/google/cloud/bigquery_v2/__init__.py
@@ -1,33 +1,44 @@
# -*- coding: utf-8 -*-
-#
-# Copyright 2018 Google LLC
+
+# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
-# https://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+#
-from __future__ import absolute_import
-
-import pkg_resources
-
-__version__ = pkg_resources.get_distribution("google-cloud-bigquery").version # noqa
-from google.cloud.bigquery_v2 import types
-from google.cloud.bigquery_v2.gapic import enums
+from .types.encryption_config import EncryptionConfiguration
+from .types.model import DeleteModelRequest
+from .types.model import GetModelRequest
+from .types.model import ListModelsRequest
+from .types.model import ListModelsResponse
+from .types.model import Model
+from .types.model import PatchModelRequest
+from .types.model_reference import ModelReference
+from .types.standard_sql import StandardSqlDataType
+from .types.standard_sql import StandardSqlField
+from .types.standard_sql import StandardSqlStructType
__all__ = (
- # google.cloud.bigquery_v2
- "__version__",
- "types",
- # google.cloud.bigquery_v2
- "enums",
+ "DeleteModelRequest",
+ "EncryptionConfiguration",
+ "GetModelRequest",
+ "ListModelsRequest",
+ "ListModelsResponse",
+ "Model",
+ "ModelReference",
+ "PatchModelRequest",
+ "StandardSqlDataType",
+ "StandardSqlField",
+ "StandardSqlStructType",
)
diff --git a/google/cloud/bigquery_v2/gapic/__init__.py b/google/cloud/bigquery_v2/gapic/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/google/cloud/bigquery_v2/gapic/enums.py b/google/cloud/bigquery_v2/gapic/enums.py
deleted file mode 100644
index 10d7c2517..000000000
--- a/google/cloud/bigquery_v2/gapic/enums.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright 2020 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Wrappers for protocol buffer enum types."""
-
-import enum
-
-
-class Model(object):
- class DataSplitMethod(enum.IntEnum):
- """
- Indicates the method to split input data into multiple tables.
-
- Attributes:
- DATA_SPLIT_METHOD_UNSPECIFIED (int)
- RANDOM (int): Splits data randomly.
- CUSTOM (int): Splits data with the user provided tags.
- SEQUENTIAL (int): Splits data sequentially.
- NO_SPLIT (int): Data split will be skipped.
- AUTO_SPLIT (int): Splits data automatically: Uses NO_SPLIT if the data size is small.
- Otherwise uses RANDOM.
- """
-
- DATA_SPLIT_METHOD_UNSPECIFIED = 0
- RANDOM = 1
- CUSTOM = 2
- SEQUENTIAL = 3
- NO_SPLIT = 4
- AUTO_SPLIT = 5
-
- class DistanceType(enum.IntEnum):
- """
- Distance metric used to compute the distance between two points.
-
- Attributes:
- DISTANCE_TYPE_UNSPECIFIED (int)
- EUCLIDEAN (int): Eculidean distance.
- COSINE (int): Cosine distance.
- """
-
- DISTANCE_TYPE_UNSPECIFIED = 0
- EUCLIDEAN = 1
- COSINE = 2
-
- class LearnRateStrategy(enum.IntEnum):
- """
- Indicates the learning rate optimization strategy to use.
-
- Attributes:
- LEARN_RATE_STRATEGY_UNSPECIFIED (int)
- LINE_SEARCH (int): Use line search to determine learning rate.
- CONSTANT (int): Use a constant learning rate.
- """
-
- LEARN_RATE_STRATEGY_UNSPECIFIED = 0
- LINE_SEARCH = 1
- CONSTANT = 2
-
- class LossType(enum.IntEnum):
- """
- Loss metric to evaluate model training performance.
-
- Attributes:
- LOSS_TYPE_UNSPECIFIED (int)
- MEAN_SQUARED_LOSS (int): Mean squared loss, used for linear regression.
- MEAN_LOG_LOSS (int): Mean log loss, used for logistic regression.
- """
-
- LOSS_TYPE_UNSPECIFIED = 0
- MEAN_SQUARED_LOSS = 1
- MEAN_LOG_LOSS = 2
-
- class ModelType(enum.IntEnum):
- """
- Indicates the type of the Model.
-
- Attributes:
- MODEL_TYPE_UNSPECIFIED (int)
- LINEAR_REGRESSION (int): Linear regression model.
- LOGISTIC_REGRESSION (int): Logistic regression based classification model.
- KMEANS (int): K-means clustering model.
- TENSORFLOW (int): [Beta] An imported TensorFlow model.
- """
-
- MODEL_TYPE_UNSPECIFIED = 0
- LINEAR_REGRESSION = 1
- LOGISTIC_REGRESSION = 2
- KMEANS = 3
- TENSORFLOW = 6
-
- class OptimizationStrategy(enum.IntEnum):
- """
- Indicates the optimization strategy used for training.
-
- Attributes:
- OPTIMIZATION_STRATEGY_UNSPECIFIED (int)
- BATCH_GRADIENT_DESCENT (int): Uses an iterative batch gradient descent algorithm.
- NORMAL_EQUATION (int): Uses a normal equation to solve linear regression problem.
- """
-
- OPTIMIZATION_STRATEGY_UNSPECIFIED = 0
- BATCH_GRADIENT_DESCENT = 1
- NORMAL_EQUATION = 2
-
- class KmeansEnums(object):
- class KmeansInitializationMethod(enum.IntEnum):
- """
- Indicates the method used to initialize the centroids for KMeans
- clustering algorithm.
-
- Attributes:
- KMEANS_INITIALIZATION_METHOD_UNSPECIFIED (int)
- RANDOM (int): Initializes the centroids randomly.
- CUSTOM (int): Initializes the centroids using data specified in
- kmeans_initialization_column.
- """
-
- KMEANS_INITIALIZATION_METHOD_UNSPECIFIED = 0
- RANDOM = 1
- CUSTOM = 2
-
-
-class StandardSqlDataType(object):
- class TypeKind(enum.IntEnum):
- """
- Attributes:
- TYPE_KIND_UNSPECIFIED (int): Invalid type.
- INT64 (int): Encoded as a string in decimal format.
- BOOL (int): Encoded as a boolean "false" or "true".
- FLOAT64 (int): Encoded as a number, or string "NaN", "Infinity" or "-Infinity".
- STRING (int): Encoded as a string value.
- BYTES (int): Encoded as a base64 string per RFC 4648, section 4.
- TIMESTAMP (int): Encoded as an RFC 3339 timestamp with mandatory "Z" time zone string:
- 1985-04-12T23:20:50.52Z
- DATE (int): Encoded as RFC 3339 full-date format string: 1985-04-12
- TIME (int): Encoded as RFC 3339 partial-time format string: 23:20:50.52
- DATETIME (int): Encoded as RFC 3339 full-date "T" partial-time: 1985-04-12T23:20:50.52
- GEOGRAPHY (int): Encoded as WKT
- NUMERIC (int): Encoded as a decimal string.
- ARRAY (int): Encoded as a list with types matching Type.array_type.
- STRUCT (int): Encoded as a list with fields of type Type.struct_type[i]. List is
- used because a JSON object cannot have duplicate field names.
- """
-
- TYPE_KIND_UNSPECIFIED = 0
- INT64 = 2
- BOOL = 5
- FLOAT64 = 7
- STRING = 8
- BYTES = 9
- TIMESTAMP = 19
- DATE = 10
- TIME = 20
- DATETIME = 21
- GEOGRAPHY = 22
- NUMERIC = 23
- ARRAY = 16
- STRUCT = 17
diff --git a/google/cloud/bigquery_v2/proto/__init__.py b/google/cloud/bigquery_v2/proto/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/google/cloud/bigquery_v2/proto/encryption_config_pb2_grpc.py b/google/cloud/bigquery_v2/proto/encryption_config_pb2_grpc.py
deleted file mode 100644
index 8a9393943..000000000
--- a/google/cloud/bigquery_v2/proto/encryption_config_pb2_grpc.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
-"""Client and server classes corresponding to protobuf-defined services."""
-import grpc
diff --git a/google/cloud/bigquery_v2/proto/location_metadata_pb2.py b/google/cloud/bigquery_v2/proto/location_metadata_pb2.py
deleted file mode 100644
index 6dd9da52e..000000000
--- a/google/cloud/bigquery_v2/proto/location_metadata_pb2.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: google/cloud/bigquery_v2/proto/location_metadata.proto
-
-import sys
-
-_b = sys.version_info[0] < 3 and (lambda x: x) or (lambda x: x.encode("latin1"))
-from google.protobuf import descriptor as _descriptor
-from google.protobuf import message as _message
-from google.protobuf import reflection as _reflection
-from google.protobuf import symbol_database as _symbol_database
-
-# @@protoc_insertion_point(imports)
-
-_sym_db = _symbol_database.Default()
-
-
-from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
-
-
-DESCRIPTOR = _descriptor.FileDescriptor(
- name="google/cloud/bigquery_v2/proto/location_metadata.proto",
- package="google.cloud.bigquery.v2",
- syntax="proto3",
- serialized_options=_b(
- "\n\034com.google.cloud.bigquery.v2B\025LocationMetadataProtoZ@google.golang.org/genproto/googleapis/cloud/bigquery/v2;bigquery"
- ),
- serialized_pb=_b(
- '\n6google/cloud/bigquery_v2/proto/location_metadata.proto\x12\x18google.cloud.bigquery.v2\x1a\x1cgoogle/api/annotations.proto".\n\x10LocationMetadata\x12\x1a\n\x12legacy_location_id\x18\x01 \x01(\tBw\n\x1c\x63om.google.cloud.bigquery.v2B\x15LocationMetadataProtoZ@google.golang.org/genproto/googleapis/cloud/bigquery/v2;bigqueryb\x06proto3'
- ),
- dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR],
-)
-
-
-_LOCATIONMETADATA = _descriptor.Descriptor(
- name="LocationMetadata",
- full_name="google.cloud.bigquery.v2.LocationMetadata",
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name="legacy_location_id",
- full_name="google.cloud.bigquery.v2.LocationMetadata.legacy_location_id",
- index=0,
- number=1,
- type=9,
- cpp_type=9,
- label=1,
- has_default_value=False,
- default_value=_b("").decode("utf-8"),
- message_type=None,
- enum_type=None,
- containing_type=None,
- is_extension=False,
- extension_scope=None,
- serialized_options=None,
- file=DESCRIPTOR,
- )
- ],
- extensions=[],
- nested_types=[],
- enum_types=[],
- serialized_options=None,
- is_extendable=False,
- syntax="proto3",
- extension_ranges=[],
- oneofs=[],
- serialized_start=114,
- serialized_end=160,
-)
-
-DESCRIPTOR.message_types_by_name["LocationMetadata"] = _LOCATIONMETADATA
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-
-LocationMetadata = _reflection.GeneratedProtocolMessageType(
- "LocationMetadata",
- (_message.Message,),
- dict(
- DESCRIPTOR=_LOCATIONMETADATA,
- __module__="google.cloud.bigquery_v2.proto.location_metadata_pb2",
- __doc__="""BigQuery-specific metadata about a location. This will be set on
- google.cloud.location.Location.metadata in Cloud Location API responses.
-
-
- Attributes:
- legacy_location_id:
- The legacy BigQuery location ID, e.g. ``EU`` for the ``europe``
- location. This is for any API consumers that need the legacy
- ``US`` and ``EU`` locations.
- """,
- # @@protoc_insertion_point(class_scope:google.cloud.bigquery.v2.LocationMetadata)
- ),
-)
-_sym_db.RegisterMessage(LocationMetadata)
-
-
-DESCRIPTOR._options = None
-# @@protoc_insertion_point(module_scope)
diff --git a/google/cloud/bigquery_v2/proto/location_metadata_pb2_grpc.py b/google/cloud/bigquery_v2/proto/location_metadata_pb2_grpc.py
deleted file mode 100644
index 07cb78fe0..000000000
--- a/google/cloud/bigquery_v2/proto/location_metadata_pb2_grpc.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
-import grpc
diff --git a/google/cloud/bigquery_v2/proto/model_pb2_grpc.py b/google/cloud/bigquery_v2/proto/model_pb2_grpc.py
deleted file mode 100644
index 13db95717..000000000
--- a/google/cloud/bigquery_v2/proto/model_pb2_grpc.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
-"""Client and server classes corresponding to protobuf-defined services."""
-import grpc
-
-from google.cloud.bigquery_v2.proto import (
- model_pb2 as google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2,
-)
-from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
-
-
-class ModelServiceStub(object):
- """Missing associated documentation comment in .proto file."""
-
- def __init__(self, channel):
- """Constructor.
-
- Args:
- channel: A grpc.Channel.
- """
- self.GetModel = channel.unary_unary(
- "/google.cloud.bigquery.v2.ModelService/GetModel",
- request_serializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.GetModelRequest.SerializeToString,
- response_deserializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.Model.FromString,
- )
- self.ListModels = channel.unary_unary(
- "/google.cloud.bigquery.v2.ModelService/ListModels",
- request_serializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.ListModelsRequest.SerializeToString,
- response_deserializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.ListModelsResponse.FromString,
- )
- self.PatchModel = channel.unary_unary(
- "/google.cloud.bigquery.v2.ModelService/PatchModel",
- request_serializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.PatchModelRequest.SerializeToString,
- response_deserializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.Model.FromString,
- )
- self.DeleteModel = channel.unary_unary(
- "/google.cloud.bigquery.v2.ModelService/DeleteModel",
- request_serializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.DeleteModelRequest.SerializeToString,
- response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
- )
-
-
-class ModelServiceServicer(object):
- """Missing associated documentation comment in .proto file."""
-
- def GetModel(self, request, context):
- """Gets the specified model resource by model ID.
- """
- context.set_code(grpc.StatusCode.UNIMPLEMENTED)
- context.set_details("Method not implemented!")
- raise NotImplementedError("Method not implemented!")
-
- def ListModels(self, request, context):
- """Lists all models in the specified dataset. Requires the READER dataset
- role.
- """
- context.set_code(grpc.StatusCode.UNIMPLEMENTED)
- context.set_details("Method not implemented!")
- raise NotImplementedError("Method not implemented!")
-
- def PatchModel(self, request, context):
- """Patch specific fields in the specified model.
- """
- context.set_code(grpc.StatusCode.UNIMPLEMENTED)
- context.set_details("Method not implemented!")
- raise NotImplementedError("Method not implemented!")
-
- def DeleteModel(self, request, context):
- """Deletes the model specified by modelId from the dataset.
- """
- context.set_code(grpc.StatusCode.UNIMPLEMENTED)
- context.set_details("Method not implemented!")
- raise NotImplementedError("Method not implemented!")
-
-
-def add_ModelServiceServicer_to_server(servicer, server):
- rpc_method_handlers = {
- "GetModel": grpc.unary_unary_rpc_method_handler(
- servicer.GetModel,
- request_deserializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.GetModelRequest.FromString,
- response_serializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.Model.SerializeToString,
- ),
- "ListModels": grpc.unary_unary_rpc_method_handler(
- servicer.ListModels,
- request_deserializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.ListModelsRequest.FromString,
- response_serializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.ListModelsResponse.SerializeToString,
- ),
- "PatchModel": grpc.unary_unary_rpc_method_handler(
- servicer.PatchModel,
- request_deserializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.PatchModelRequest.FromString,
- response_serializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.Model.SerializeToString,
- ),
- "DeleteModel": grpc.unary_unary_rpc_method_handler(
- servicer.DeleteModel,
- request_deserializer=google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.DeleteModelRequest.FromString,
- response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
- ),
- }
- generic_handler = grpc.method_handlers_generic_handler(
- "google.cloud.bigquery.v2.ModelService", rpc_method_handlers
- )
- server.add_generic_rpc_handlers((generic_handler,))
-
-
-# This class is part of an EXPERIMENTAL API.
-class ModelService(object):
- """Missing associated documentation comment in .proto file."""
-
- @staticmethod
- def GetModel(
- request,
- target,
- options=(),
- channel_credentials=None,
- call_credentials=None,
- compression=None,
- wait_for_ready=None,
- timeout=None,
- metadata=None,
- ):
- return grpc.experimental.unary_unary(
- request,
- target,
- "/google.cloud.bigquery.v2.ModelService/GetModel",
- google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.GetModelRequest.SerializeToString,
- google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.Model.FromString,
- options,
- channel_credentials,
- call_credentials,
- compression,
- wait_for_ready,
- timeout,
- metadata,
- )
-
- @staticmethod
- def ListModels(
- request,
- target,
- options=(),
- channel_credentials=None,
- call_credentials=None,
- compression=None,
- wait_for_ready=None,
- timeout=None,
- metadata=None,
- ):
- return grpc.experimental.unary_unary(
- request,
- target,
- "/google.cloud.bigquery.v2.ModelService/ListModels",
- google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.ListModelsRequest.SerializeToString,
- google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.ListModelsResponse.FromString,
- options,
- channel_credentials,
- call_credentials,
- compression,
- wait_for_ready,
- timeout,
- metadata,
- )
-
- @staticmethod
- def PatchModel(
- request,
- target,
- options=(),
- channel_credentials=None,
- call_credentials=None,
- compression=None,
- wait_for_ready=None,
- timeout=None,
- metadata=None,
- ):
- return grpc.experimental.unary_unary(
- request,
- target,
- "/google.cloud.bigquery.v2.ModelService/PatchModel",
- google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.PatchModelRequest.SerializeToString,
- google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.Model.FromString,
- options,
- channel_credentials,
- call_credentials,
- compression,
- wait_for_ready,
- timeout,
- metadata,
- )
-
- @staticmethod
- def DeleteModel(
- request,
- target,
- options=(),
- channel_credentials=None,
- call_credentials=None,
- compression=None,
- wait_for_ready=None,
- timeout=None,
- metadata=None,
- ):
- return grpc.experimental.unary_unary(
- request,
- target,
- "/google.cloud.bigquery.v2.ModelService/DeleteModel",
- google_dot_cloud_dot_bigquery__v2_dot_proto_dot_model__pb2.DeleteModelRequest.SerializeToString,
- google_dot_protobuf_dot_empty__pb2.Empty.FromString,
- options,
- channel_credentials,
- call_credentials,
- compression,
- wait_for_ready,
- timeout,
- metadata,
- )
diff --git a/google/cloud/bigquery_v2/proto/model_reference_pb2_grpc.py b/google/cloud/bigquery_v2/proto/model_reference_pb2_grpc.py
deleted file mode 100644
index 8a9393943..000000000
--- a/google/cloud/bigquery_v2/proto/model_reference_pb2_grpc.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
-"""Client and server classes corresponding to protobuf-defined services."""
-import grpc
diff --git a/google/cloud/bigquery_v2/proto/standard_sql_pb2_grpc.py b/google/cloud/bigquery_v2/proto/standard_sql_pb2_grpc.py
deleted file mode 100644
index 8a9393943..000000000
--- a/google/cloud/bigquery_v2/proto/standard_sql_pb2_grpc.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
-"""Client and server classes corresponding to protobuf-defined services."""
-import grpc
diff --git a/google/cloud/bigquery_v2/py.typed b/google/cloud/bigquery_v2/py.typed
new file mode 100644
index 000000000..e73777993
--- /dev/null
+++ b/google/cloud/bigquery_v2/py.typed
@@ -0,0 +1,2 @@
+# Marker file for PEP 561.
+# The google-cloud-bigquery package uses inline types.
diff --git a/google/cloud/bigquery_v2/types.py b/google/cloud/bigquery_v2/types.py
deleted file mode 100644
index 7d4f9b732..000000000
--- a/google/cloud/bigquery_v2/types.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright 2020 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-from __future__ import absolute_import
-import sys
-
-from google.api_core.protobuf_helpers import get_messages
-
-from google.cloud.bigquery_v2.proto import encryption_config_pb2
-from google.cloud.bigquery_v2.proto import model_pb2
-from google.cloud.bigquery_v2.proto import model_reference_pb2
-from google.cloud.bigquery_v2.proto import standard_sql_pb2
-from google.protobuf import empty_pb2
-from google.protobuf import timestamp_pb2
-from google.protobuf import wrappers_pb2
-
-
-_shared_modules = [
- empty_pb2,
- timestamp_pb2,
- wrappers_pb2,
-]
-
-_local_modules = [
- encryption_config_pb2,
- model_pb2,
- model_reference_pb2,
- standard_sql_pb2,
-]
-
-names = []
-
-for module in _shared_modules: # pragma: NO COVER
- for name, message in get_messages(module).items():
- setattr(sys.modules[__name__], name, message)
- names.append(name)
-for module in _local_modules:
- for name, message in get_messages(module).items():
- message.__module__ = "google.cloud.bigquery_v2.types"
- setattr(sys.modules[__name__], name, message)
- names.append(name)
-
-
-__all__ = tuple(sorted(names))
diff --git a/google/cloud/bigquery_v2/types/__init__.py b/google/cloud/bigquery_v2/types/__init__.py
new file mode 100644
index 000000000..a8839c74e
--- /dev/null
+++ b/google/cloud/bigquery_v2/types/__init__.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from .encryption_config import EncryptionConfiguration
+from .model_reference import ModelReference
+from .standard_sql import (
+ StandardSqlDataType,
+ StandardSqlField,
+ StandardSqlStructType,
+)
+from .model import (
+ Model,
+ GetModelRequest,
+ PatchModelRequest,
+ DeleteModelRequest,
+ ListModelsRequest,
+ ListModelsResponse,
+)
+
+
+__all__ = (
+ "EncryptionConfiguration",
+ "ModelReference",
+ "StandardSqlDataType",
+ "StandardSqlField",
+ "StandardSqlStructType",
+ "Model",
+ "GetModelRequest",
+ "PatchModelRequest",
+ "DeleteModelRequest",
+ "ListModelsRequest",
+ "ListModelsResponse",
+)
diff --git a/google/cloud/bigquery_v2/types/encryption_config.py b/google/cloud/bigquery_v2/types/encryption_config.py
new file mode 100644
index 000000000..6fb90f340
--- /dev/null
+++ b/google/cloud/bigquery_v2/types/encryption_config.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import proto # type: ignore
+
+
+from google.protobuf import wrappers_pb2 as wrappers # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.bigquery.v2", manifest={"EncryptionConfiguration",},
+)
+
+
+class EncryptionConfiguration(proto.Message):
+ r"""
+
+ Attributes:
+ kms_key_name (~.wrappers.StringValue):
+ Optional. Describes the Cloud KMS encryption
+ key that will be used to protect destination
+ BigQuery table. The BigQuery Service Account
+ associated with your project requires access to
+ this encryption key.
+ """
+
+ kms_key_name = proto.Field(proto.MESSAGE, number=1, message=wrappers.StringValue,)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/bigquery_v2/types/model.py b/google/cloud/bigquery_v2/types/model.py
new file mode 100644
index 000000000..a00720d48
--- /dev/null
+++ b/google/cloud/bigquery_v2/types/model.py
@@ -0,0 +1,966 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import proto # type: ignore
+
+
+from google.cloud.bigquery_v2.types import encryption_config
+from google.cloud.bigquery_v2.types import model_reference as gcb_model_reference
+from google.cloud.bigquery_v2.types import standard_sql
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+from google.protobuf import wrappers_pb2 as wrappers # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.bigquery.v2",
+ manifest={
+ "Model",
+ "GetModelRequest",
+ "PatchModelRequest",
+ "DeleteModelRequest",
+ "ListModelsRequest",
+ "ListModelsResponse",
+ },
+)
+
+
+class Model(proto.Message):
+ r"""
+
+ Attributes:
+ etag (str):
+ Output only. A hash of this resource.
+ model_reference (~.gcb_model_reference.ModelReference):
+ Required. Unique identifier for this model.
+ creation_time (int):
+ Output only. The time when this model was
+ created, in millisecs since the epoch.
+ last_modified_time (int):
+ Output only. The time when this model was
+ last modified, in millisecs since the epoch.
+ description (str):
+ Optional. A user-friendly description of this
+ model.
+ friendly_name (str):
+ Optional. A descriptive name for this model.
+ labels (Sequence[~.gcb_model.Model.LabelsEntry]):
+ The labels associated with this model. You
+ can use these to organize and group your models.
+ Label keys and values can be no longer than 63
+ characters, can only contain lowercase letters,
+ numeric characters, underscores and dashes.
+ International characters are allowed. Label
+ values are optional. Label keys must start with
+ a letter and each label in the list must have a
+ different key.
+ expiration_time (int):
+ Optional. The time when this model expires,
+ in milliseconds since the epoch. If not present,
+ the model will persist indefinitely. Expired
+ models will be deleted and their storage
+ reclaimed. The defaultTableExpirationMs
+ property of the encapsulating dataset can be
+ used to set a default expirationTime on newly
+ created models.
+ location (str):
+ Output only. The geographic location where
+ the model resides. This value is inherited from
+ the dataset.
+ encryption_configuration (~.encryption_config.EncryptionConfiguration):
+ Custom encryption configuration (e.g., Cloud
+ KMS keys). This shows the encryption
+ configuration of the model data while stored in
+ BigQuery storage.
+ model_type (~.gcb_model.Model.ModelType):
+ Output only. Type of the model resource.
+ training_runs (Sequence[~.gcb_model.Model.TrainingRun]):
+ Output only. Information for all training runs in increasing
+ order of start_time.
+ feature_columns (Sequence[~.standard_sql.StandardSqlField]):
+ Output only. Input feature columns that were
+ used to train this model.
+ label_columns (Sequence[~.standard_sql.StandardSqlField]):
+ Output only. Label columns that were used to train this
+ model. The output of the model will have a `predicted_`
+ prefix to these columns.
+ """
+
+ class ModelType(proto.Enum):
+ r"""Indicates the type of the Model."""
+ MODEL_TYPE_UNSPECIFIED = 0
+ LINEAR_REGRESSION = 1
+ LOGISTIC_REGRESSION = 2
+ KMEANS = 3
+ TENSORFLOW = 6
+
+ class LossType(proto.Enum):
+ r"""Loss metric to evaluate model training performance."""
+ LOSS_TYPE_UNSPECIFIED = 0
+ MEAN_SQUARED_LOSS = 1
+ MEAN_LOG_LOSS = 2
+
+ class DistanceType(proto.Enum):
+ r"""Distance metric used to compute the distance between two
+ points.
+ """
+ DISTANCE_TYPE_UNSPECIFIED = 0
+ EUCLIDEAN = 1
+ COSINE = 2
+
+ class DataSplitMethod(proto.Enum):
+ r"""Indicates the method to split input data into multiple
+ tables.
+ """
+ DATA_SPLIT_METHOD_UNSPECIFIED = 0
+ RANDOM = 1
+ CUSTOM = 2
+ SEQUENTIAL = 3
+ NO_SPLIT = 4
+ AUTO_SPLIT = 5
+
+ class LearnRateStrategy(proto.Enum):
+ r"""Indicates the learning rate optimization strategy to use."""
+ LEARN_RATE_STRATEGY_UNSPECIFIED = 0
+ LINE_SEARCH = 1
+ CONSTANT = 2
+
+ class OptimizationStrategy(proto.Enum):
+ r"""Indicates the optimization strategy used for training."""
+ OPTIMIZATION_STRATEGY_UNSPECIFIED = 0
+ BATCH_GRADIENT_DESCENT = 1
+ NORMAL_EQUATION = 2
+
+ class KmeansEnums(proto.Message):
+ r""""""
+
+ class KmeansInitializationMethod(proto.Enum):
+ r"""Indicates the method used to initialize the centroids for
+ KMeans clustering algorithm.
+ """
+ KMEANS_INITIALIZATION_METHOD_UNSPECIFIED = 0
+ RANDOM = 1
+ CUSTOM = 2
+
+ class RegressionMetrics(proto.Message):
+ r"""Evaluation metrics for regression and explicit feedback type
+ matrix factorization models.
+
+ Attributes:
+ mean_absolute_error (~.wrappers.DoubleValue):
+ Mean absolute error.
+ mean_squared_error (~.wrappers.DoubleValue):
+ Mean squared error.
+ mean_squared_log_error (~.wrappers.DoubleValue):
+ Mean squared log error.
+ median_absolute_error (~.wrappers.DoubleValue):
+ Median absolute error.
+ r_squared (~.wrappers.DoubleValue):
+ R^2 score.
+ """
+
+ mean_absolute_error = proto.Field(
+ proto.MESSAGE, number=1, message=wrappers.DoubleValue,
+ )
+
+ mean_squared_error = proto.Field(
+ proto.MESSAGE, number=2, message=wrappers.DoubleValue,
+ )
+
+ mean_squared_log_error = proto.Field(
+ proto.MESSAGE, number=3, message=wrappers.DoubleValue,
+ )
+
+ median_absolute_error = proto.Field(
+ proto.MESSAGE, number=4, message=wrappers.DoubleValue,
+ )
+
+ r_squared = proto.Field(proto.MESSAGE, number=5, message=wrappers.DoubleValue,)
+
+ class AggregateClassificationMetrics(proto.Message):
+ r"""Aggregate metrics for classification/classifier models. For
+ multi-class models, the metrics are either macro-averaged or
+ micro-averaged. When macro-averaged, the metrics are calculated
+ for each label and then an unweighted average is taken of those
+ values. When micro-averaged, the metric is calculated globally
+ by counting the total number of correctly predicted rows.
+
+ Attributes:
+ precision (~.wrappers.DoubleValue):
+ Precision is the fraction of actual positive
+ predictions that had positive actual labels. For
+ multiclass this is a macro-averaged metric
+ treating each class as a binary classifier.
+ recall (~.wrappers.DoubleValue):
+ Recall is the fraction of actual positive
+ labels that were given a positive prediction.
+ For multiclass this is a macro-averaged metric.
+ accuracy (~.wrappers.DoubleValue):
+ Accuracy is the fraction of predictions given
+ the correct label. For multiclass this is a
+ micro-averaged metric.
+ threshold (~.wrappers.DoubleValue):
+ Threshold at which the metrics are computed.
+ For binary classification models this is the
+ positive class threshold. For multi-class
+ classfication models this is the confidence
+ threshold.
+ f1_score (~.wrappers.DoubleValue):
+ The F1 score is an average of recall and
+ precision. For multiclass this is a macro-
+ averaged metric.
+ log_loss (~.wrappers.DoubleValue):
+ Logarithmic Loss. For multiclass this is a
+ macro-averaged metric.
+ roc_auc (~.wrappers.DoubleValue):
+ Area Under a ROC Curve. For multiclass this
+ is a macro-averaged metric.
+ """
+
+ precision = proto.Field(proto.MESSAGE, number=1, message=wrappers.DoubleValue,)
+
+ recall = proto.Field(proto.MESSAGE, number=2, message=wrappers.DoubleValue,)
+
+ accuracy = proto.Field(proto.MESSAGE, number=3, message=wrappers.DoubleValue,)
+
+ threshold = proto.Field(proto.MESSAGE, number=4, message=wrappers.DoubleValue,)
+
+ f1_score = proto.Field(proto.MESSAGE, number=5, message=wrappers.DoubleValue,)
+
+ log_loss = proto.Field(proto.MESSAGE, number=6, message=wrappers.DoubleValue,)
+
+ roc_auc = proto.Field(proto.MESSAGE, number=7, message=wrappers.DoubleValue,)
+
+ class BinaryClassificationMetrics(proto.Message):
+ r"""Evaluation metrics for binary classification/classifier
+ models.
+
+ Attributes:
+ aggregate_classification_metrics (~.gcb_model.Model.AggregateClassificationMetrics):
+ Aggregate classification metrics.
+ binary_confusion_matrix_list (Sequence[~.gcb_model.Model.BinaryClassificationMetrics.BinaryConfusionMatrix]):
+ Binary confusion matrix at multiple
+ thresholds.
+ positive_label (str):
+ Label representing the positive class.
+ negative_label (str):
+ Label representing the negative class.
+ """
+
+ class BinaryConfusionMatrix(proto.Message):
+ r"""Confusion matrix for binary classification models.
+
+ Attributes:
+ positive_class_threshold (~.wrappers.DoubleValue):
+ Threshold value used when computing each of
+ the following metric.
+ true_positives (~.wrappers.Int64Value):
+ Number of true samples predicted as true.
+ false_positives (~.wrappers.Int64Value):
+ Number of false samples predicted as true.
+ true_negatives (~.wrappers.Int64Value):
+ Number of true samples predicted as false.
+ false_negatives (~.wrappers.Int64Value):
+ Number of false samples predicted as false.
+ precision (~.wrappers.DoubleValue):
+ The fraction of actual positive predictions
+ that had positive actual labels.
+ recall (~.wrappers.DoubleValue):
+ The fraction of actual positive labels that
+ were given a positive prediction.
+ f1_score (~.wrappers.DoubleValue):
+ The equally weighted average of recall and
+ precision.
+ accuracy (~.wrappers.DoubleValue):
+ The fraction of predictions given the correct
+ label.
+ """
+
+ positive_class_threshold = proto.Field(
+ proto.MESSAGE, number=1, message=wrappers.DoubleValue,
+ )
+
+ true_positives = proto.Field(
+ proto.MESSAGE, number=2, message=wrappers.Int64Value,
+ )
+
+ false_positives = proto.Field(
+ proto.MESSAGE, number=3, message=wrappers.Int64Value,
+ )
+
+ true_negatives = proto.Field(
+ proto.MESSAGE, number=4, message=wrappers.Int64Value,
+ )
+
+ false_negatives = proto.Field(
+ proto.MESSAGE, number=5, message=wrappers.Int64Value,
+ )
+
+ precision = proto.Field(
+ proto.MESSAGE, number=6, message=wrappers.DoubleValue,
+ )
+
+ recall = proto.Field(proto.MESSAGE, number=7, message=wrappers.DoubleValue,)
+
+ f1_score = proto.Field(
+ proto.MESSAGE, number=8, message=wrappers.DoubleValue,
+ )
+
+ accuracy = proto.Field(
+ proto.MESSAGE, number=9, message=wrappers.DoubleValue,
+ )
+
+ aggregate_classification_metrics = proto.Field(
+ proto.MESSAGE, number=1, message="Model.AggregateClassificationMetrics",
+ )
+
+ binary_confusion_matrix_list = proto.RepeatedField(
+ proto.MESSAGE,
+ number=2,
+ message="Model.BinaryClassificationMetrics.BinaryConfusionMatrix",
+ )
+
+ positive_label = proto.Field(proto.STRING, number=3)
+
+ negative_label = proto.Field(proto.STRING, number=4)
+
+ class MultiClassClassificationMetrics(proto.Message):
+ r"""Evaluation metrics for multi-class classification/classifier
+ models.
+
+ Attributes:
+ aggregate_classification_metrics (~.gcb_model.Model.AggregateClassificationMetrics):
+ Aggregate classification metrics.
+ confusion_matrix_list (Sequence[~.gcb_model.Model.MultiClassClassificationMetrics.ConfusionMatrix]):
+ Confusion matrix at different thresholds.
+ """
+
+ class ConfusionMatrix(proto.Message):
+ r"""Confusion matrix for multi-class classification models.
+
+ Attributes:
+ confidence_threshold (~.wrappers.DoubleValue):
+ Confidence threshold used when computing the
+ entries of the confusion matrix.
+ rows (Sequence[~.gcb_model.Model.MultiClassClassificationMetrics.ConfusionMatrix.Row]):
+ One row per actual label.
+ """
+
+ class Entry(proto.Message):
+ r"""A single entry in the confusion matrix.
+
+ Attributes:
+ predicted_label (str):
+ The predicted label. For confidence_threshold > 0, we will
+ also add an entry indicating the number of items under the
+ confidence threshold.
+ item_count (~.wrappers.Int64Value):
+ Number of items being predicted as this
+ label.
+ """
+
+ predicted_label = proto.Field(proto.STRING, number=1)
+
+ item_count = proto.Field(
+ proto.MESSAGE, number=2, message=wrappers.Int64Value,
+ )
+
+ class Row(proto.Message):
+ r"""A single row in the confusion matrix.
+
+ Attributes:
+ actual_label (str):
+ The original label of this row.
+ entries (Sequence[~.gcb_model.Model.MultiClassClassificationMetrics.ConfusionMatrix.Entry]):
+ Info describing predicted label distribution.
+ """
+
+ actual_label = proto.Field(proto.STRING, number=1)
+
+ entries = proto.RepeatedField(
+ proto.MESSAGE,
+ number=2,
+ message="Model.MultiClassClassificationMetrics.ConfusionMatrix.Entry",
+ )
+
+ confidence_threshold = proto.Field(
+ proto.MESSAGE, number=1, message=wrappers.DoubleValue,
+ )
+
+ rows = proto.RepeatedField(
+ proto.MESSAGE,
+ number=2,
+ message="Model.MultiClassClassificationMetrics.ConfusionMatrix.Row",
+ )
+
+ aggregate_classification_metrics = proto.Field(
+ proto.MESSAGE, number=1, message="Model.AggregateClassificationMetrics",
+ )
+
+ confusion_matrix_list = proto.RepeatedField(
+ proto.MESSAGE,
+ number=2,
+ message="Model.MultiClassClassificationMetrics.ConfusionMatrix",
+ )
+
+ class ClusteringMetrics(proto.Message):
+ r"""Evaluation metrics for clustering models.
+
+ Attributes:
+ davies_bouldin_index (~.wrappers.DoubleValue):
+ Davies-Bouldin index.
+ mean_squared_distance (~.wrappers.DoubleValue):
+ Mean of squared distances between each sample
+ to its cluster centroid.
+ clusters (Sequence[~.gcb_model.Model.ClusteringMetrics.Cluster]):
+ [Beta] Information for all clusters.
+ """
+
+ class Cluster(proto.Message):
+ r"""Message containing the information about one cluster.
+
+ Attributes:
+ centroid_id (int):
+ Centroid id.
+ feature_values (Sequence[~.gcb_model.Model.ClusteringMetrics.Cluster.FeatureValue]):
+ Values of highly variant features for this
+ cluster.
+ count (~.wrappers.Int64Value):
+ Count of training data rows that were
+ assigned to this cluster.
+ """
+
+ class FeatureValue(proto.Message):
+ r"""Representative value of a single feature within the cluster.
+
+ Attributes:
+ feature_column (str):
+ The feature column name.
+ numerical_value (~.wrappers.DoubleValue):
+ The numerical feature value. This is the
+ centroid value for this feature.
+ categorical_value (~.gcb_model.Model.ClusteringMetrics.Cluster.FeatureValue.CategoricalValue):
+ The categorical feature value.
+ """
+
+ class CategoricalValue(proto.Message):
+ r"""Representative value of a categorical feature.
+
+ Attributes:
+ category_counts (Sequence[~.gcb_model.Model.ClusteringMetrics.Cluster.FeatureValue.CategoricalValue.CategoryCount]):
+ Counts of all categories for the categorical feature. If
+ there are more than ten categories, we return top ten (by
+ count) and return one more CategoryCount with category
+ "*OTHER*" and count as aggregate counts of remaining
+ categories.
+ """
+
+ class CategoryCount(proto.Message):
+ r"""Represents the count of a single category within the cluster.
+
+ Attributes:
+ category (str):
+ The name of category.
+ count (~.wrappers.Int64Value):
+ The count of training samples matching the
+ category within the cluster.
+ """
+
+ category = proto.Field(proto.STRING, number=1)
+
+ count = proto.Field(
+ proto.MESSAGE, number=2, message=wrappers.Int64Value,
+ )
+
+ category_counts = proto.RepeatedField(
+ proto.MESSAGE,
+ number=1,
+ message="Model.ClusteringMetrics.Cluster.FeatureValue.CategoricalValue.CategoryCount",
+ )
+
+ feature_column = proto.Field(proto.STRING, number=1)
+
+ numerical_value = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ oneof="value",
+ message=wrappers.DoubleValue,
+ )
+
+ categorical_value = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ oneof="value",
+ message="Model.ClusteringMetrics.Cluster.FeatureValue.CategoricalValue",
+ )
+
+ centroid_id = proto.Field(proto.INT64, number=1)
+
+ feature_values = proto.RepeatedField(
+ proto.MESSAGE,
+ number=2,
+ message="Model.ClusteringMetrics.Cluster.FeatureValue",
+ )
+
+ count = proto.Field(proto.MESSAGE, number=3, message=wrappers.Int64Value,)
+
+ davies_bouldin_index = proto.Field(
+ proto.MESSAGE, number=1, message=wrappers.DoubleValue,
+ )
+
+ mean_squared_distance = proto.Field(
+ proto.MESSAGE, number=2, message=wrappers.DoubleValue,
+ )
+
+ clusters = proto.RepeatedField(
+ proto.MESSAGE, number=3, message="Model.ClusteringMetrics.Cluster",
+ )
+
+ class EvaluationMetrics(proto.Message):
+ r"""Evaluation metrics of a model. These are either computed on
+ all training data or just the eval data based on whether eval
+ data was used during training. These are not present for
+ imported models.
+
+ Attributes:
+ regression_metrics (~.gcb_model.Model.RegressionMetrics):
+ Populated for regression models and explicit
+ feedback type matrix factorization models.
+ binary_classification_metrics (~.gcb_model.Model.BinaryClassificationMetrics):
+ Populated for binary
+ classification/classifier models.
+ multi_class_classification_metrics (~.gcb_model.Model.MultiClassClassificationMetrics):
+ Populated for multi-class
+ classification/classifier models.
+ clustering_metrics (~.gcb_model.Model.ClusteringMetrics):
+ Populated for clustering models.
+ """
+
+ regression_metrics = proto.Field(
+ proto.MESSAGE, number=1, oneof="metrics", message="Model.RegressionMetrics",
+ )
+
+ binary_classification_metrics = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ oneof="metrics",
+ message="Model.BinaryClassificationMetrics",
+ )
+
+ multi_class_classification_metrics = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ oneof="metrics",
+ message="Model.MultiClassClassificationMetrics",
+ )
+
+ clustering_metrics = proto.Field(
+ proto.MESSAGE, number=4, oneof="metrics", message="Model.ClusteringMetrics",
+ )
+
+ class TrainingRun(proto.Message):
+ r"""Information about a single training query run for the model.
+
+ Attributes:
+ training_options (~.gcb_model.Model.TrainingRun.TrainingOptions):
+ Options that were used for this training run,
+ includes user specified and default options that
+ were used.
+ start_time (~.timestamp.Timestamp):
+ The start time of this training run.
+ results (Sequence[~.gcb_model.Model.TrainingRun.IterationResult]):
+ Output of each iteration run, results.size() <=
+ max_iterations.
+ evaluation_metrics (~.gcb_model.Model.EvaluationMetrics):
+ The evaluation metrics over training/eval
+ data that were computed at the end of training.
+ """
+
+ class TrainingOptions(proto.Message):
+ r"""
+
+ Attributes:
+ max_iterations (int):
+ The maximum number of iterations in training.
+ Used only for iterative training algorithms.
+ loss_type (~.gcb_model.Model.LossType):
+ Type of loss function used during training
+ run.
+ learn_rate (float):
+ Learning rate in training. Used only for
+ iterative training algorithms.
+ l1_regularization (~.wrappers.DoubleValue):
+ L1 regularization coefficient.
+ l2_regularization (~.wrappers.DoubleValue):
+ L2 regularization coefficient.
+ min_relative_progress (~.wrappers.DoubleValue):
+ When early_stop is true, stops training when accuracy
+ improvement is less than 'min_relative_progress'. Used only
+ for iterative training algorithms.
+ warm_start (~.wrappers.BoolValue):
+ Whether to train a model from the last
+ checkpoint.
+ early_stop (~.wrappers.BoolValue):
+ Whether to stop early when the loss doesn't improve
+ significantly any more (compared to min_relative_progress).
+ Used only for iterative training algorithms.
+ input_label_columns (Sequence[str]):
+ Name of input label columns in training data.
+ data_split_method (~.gcb_model.Model.DataSplitMethod):
+ The data split type for training and
+ evaluation, e.g. RANDOM.
+ data_split_eval_fraction (float):
+ The fraction of evaluation data over the
+ whole input data. The rest of data will be used
+ as training data. The format should be double.
+ Accurate to two decimal places.
+ Default value is 0.2.
+ data_split_column (str):
+ The column to split data with. This column won't be used as
+ a feature.
+
+ 1. When data_split_method is CUSTOM, the corresponding
+ column should be boolean. The rows with true value tag
+ are eval data, and the false are training data.
+ 2. When data_split_method is SEQ, the first
+ DATA_SPLIT_EVAL_FRACTION rows (from smallest to largest)
+ in the corresponding column are used as training data,
+ and the rest are eval data. It respects the order in
+ Orderable data types:
+ https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#data-type-properties
+ learn_rate_strategy (~.gcb_model.Model.LearnRateStrategy):
+ The strategy to determine learn rate for the
+ current iteration.
+ initial_learn_rate (float):
+ Specifies the initial learning rate for the
+ line search learn rate strategy.
+ label_class_weights (Sequence[~.gcb_model.Model.TrainingRun.TrainingOptions.LabelClassWeightsEntry]):
+ Weights associated with each label class, for
+ rebalancing the training data. Only applicable
+ for classification models.
+ distance_type (~.gcb_model.Model.DistanceType):
+ Distance type for clustering models.
+ num_clusters (int):
+ Number of clusters for clustering models.
+ model_uri (str):
+ [Beta] Google Cloud Storage URI from which the model was
+ imported. Only applicable for imported models.
+ optimization_strategy (~.gcb_model.Model.OptimizationStrategy):
+ Optimization strategy for training linear
+ regression models.
+ kmeans_initialization_method (~.gcb_model.Model.KmeansEnums.KmeansInitializationMethod):
+ The method used to initialize the centroids
+ for kmeans algorithm.
+ kmeans_initialization_column (str):
+ The column used to provide the initial centroids for kmeans
+ algorithm when kmeans_initialization_method is CUSTOM.
+ """
+
+ max_iterations = proto.Field(proto.INT64, number=1)
+
+ loss_type = proto.Field(proto.ENUM, number=2, enum="Model.LossType",)
+
+ learn_rate = proto.Field(proto.DOUBLE, number=3)
+
+ l1_regularization = proto.Field(
+ proto.MESSAGE, number=4, message=wrappers.DoubleValue,
+ )
+
+ l2_regularization = proto.Field(
+ proto.MESSAGE, number=5, message=wrappers.DoubleValue,
+ )
+
+ min_relative_progress = proto.Field(
+ proto.MESSAGE, number=6, message=wrappers.DoubleValue,
+ )
+
+ warm_start = proto.Field(
+ proto.MESSAGE, number=7, message=wrappers.BoolValue,
+ )
+
+ early_stop = proto.Field(
+ proto.MESSAGE, number=8, message=wrappers.BoolValue,
+ )
+
+ input_label_columns = proto.RepeatedField(proto.STRING, number=9)
+
+ data_split_method = proto.Field(
+ proto.ENUM, number=10, enum="Model.DataSplitMethod",
+ )
+
+ data_split_eval_fraction = proto.Field(proto.DOUBLE, number=11)
+
+ data_split_column = proto.Field(proto.STRING, number=12)
+
+ learn_rate_strategy = proto.Field(
+ proto.ENUM, number=13, enum="Model.LearnRateStrategy",
+ )
+
+ initial_learn_rate = proto.Field(proto.DOUBLE, number=16)
+
+ label_class_weights = proto.MapField(proto.STRING, proto.DOUBLE, number=17)
+
+ distance_type = proto.Field(
+ proto.ENUM, number=20, enum="Model.DistanceType",
+ )
+
+ num_clusters = proto.Field(proto.INT64, number=21)
+
+ model_uri = proto.Field(proto.STRING, number=22)
+
+ optimization_strategy = proto.Field(
+ proto.ENUM, number=23, enum="Model.OptimizationStrategy",
+ )
+
+ kmeans_initialization_method = proto.Field(
+ proto.ENUM,
+ number=33,
+ enum="Model.KmeansEnums.KmeansInitializationMethod",
+ )
+
+ kmeans_initialization_column = proto.Field(proto.STRING, number=34)
+
+ class IterationResult(proto.Message):
+ r"""Information about a single iteration of the training run.
+
+ Attributes:
+ index (~.wrappers.Int32Value):
+ Index of the iteration, 0 based.
+ duration_ms (~.wrappers.Int64Value):
+ Time taken to run the iteration in
+ milliseconds.
+ training_loss (~.wrappers.DoubleValue):
+ Loss computed on the training data at the end
+ of iteration.
+ eval_loss (~.wrappers.DoubleValue):
+ Loss computed on the eval data at the end of
+ iteration.
+ learn_rate (float):
+ Learn rate used for this iteration.
+ cluster_infos (Sequence[~.gcb_model.Model.TrainingRun.IterationResult.ClusterInfo]):
+ Information about top clusters for clustering
+ models.
+ """
+
+ class ClusterInfo(proto.Message):
+ r"""Information about a single cluster for clustering model.
+
+ Attributes:
+ centroid_id (int):
+ Centroid id.
+ cluster_radius (~.wrappers.DoubleValue):
+ Cluster radius, the average distance from
+ centroid to each point assigned to the cluster.
+ cluster_size (~.wrappers.Int64Value):
+ Cluster size, the total number of points
+ assigned to the cluster.
+ """
+
+ centroid_id = proto.Field(proto.INT64, number=1)
+
+ cluster_radius = proto.Field(
+ proto.MESSAGE, number=2, message=wrappers.DoubleValue,
+ )
+
+ cluster_size = proto.Field(
+ proto.MESSAGE, number=3, message=wrappers.Int64Value,
+ )
+
+ index = proto.Field(proto.MESSAGE, number=1, message=wrappers.Int32Value,)
+
+ duration_ms = proto.Field(
+ proto.MESSAGE, number=4, message=wrappers.Int64Value,
+ )
+
+ training_loss = proto.Field(
+ proto.MESSAGE, number=5, message=wrappers.DoubleValue,
+ )
+
+ eval_loss = proto.Field(
+ proto.MESSAGE, number=6, message=wrappers.DoubleValue,
+ )
+
+ learn_rate = proto.Field(proto.DOUBLE, number=7)
+
+ cluster_infos = proto.RepeatedField(
+ proto.MESSAGE,
+ number=8,
+ message="Model.TrainingRun.IterationResult.ClusterInfo",
+ )
+
+ training_options = proto.Field(
+ proto.MESSAGE, number=1, message="Model.TrainingRun.TrainingOptions",
+ )
+
+ start_time = proto.Field(proto.MESSAGE, number=8, message=timestamp.Timestamp,)
+
+ results = proto.RepeatedField(
+ proto.MESSAGE, number=6, message="Model.TrainingRun.IterationResult",
+ )
+
+ evaluation_metrics = proto.Field(
+ proto.MESSAGE, number=7, message="Model.EvaluationMetrics",
+ )
+
+ etag = proto.Field(proto.STRING, number=1)
+
+ model_reference = proto.Field(
+ proto.MESSAGE, number=2, message=gcb_model_reference.ModelReference,
+ )
+
+ creation_time = proto.Field(proto.INT64, number=5)
+
+ last_modified_time = proto.Field(proto.INT64, number=6)
+
+ description = proto.Field(proto.STRING, number=12)
+
+ friendly_name = proto.Field(proto.STRING, number=14)
+
+ labels = proto.MapField(proto.STRING, proto.STRING, number=15)
+
+ expiration_time = proto.Field(proto.INT64, number=16)
+
+ location = proto.Field(proto.STRING, number=13)
+
+ encryption_configuration = proto.Field(
+ proto.MESSAGE, number=17, message=encryption_config.EncryptionConfiguration,
+ )
+
+ model_type = proto.Field(proto.ENUM, number=7, enum=ModelType,)
+
+ training_runs = proto.RepeatedField(proto.MESSAGE, number=9, message=TrainingRun,)
+
+ feature_columns = proto.RepeatedField(
+ proto.MESSAGE, number=10, message=standard_sql.StandardSqlField,
+ )
+
+ label_columns = proto.RepeatedField(
+ proto.MESSAGE, number=11, message=standard_sql.StandardSqlField,
+ )
+
+
+class GetModelRequest(proto.Message):
+ r"""
+
+ Attributes:
+ project_id (str):
+ Required. Project ID of the requested model.
+ dataset_id (str):
+ Required. Dataset ID of the requested model.
+ model_id (str):
+ Required. Model ID of the requested model.
+ """
+
+ project_id = proto.Field(proto.STRING, number=1)
+
+ dataset_id = proto.Field(proto.STRING, number=2)
+
+ model_id = proto.Field(proto.STRING, number=3)
+
+
+class PatchModelRequest(proto.Message):
+ r"""
+
+ Attributes:
+ project_id (str):
+ Required. Project ID of the model to patch.
+ dataset_id (str):
+ Required. Dataset ID of the model to patch.
+ model_id (str):
+ Required. Model ID of the model to patch.
+ model (~.gcb_model.Model):
+ Required. Patched model.
+ Follows RFC5789 patch semantics. Missing fields
+ are not updated. To clear a field, explicitly
+ set to default value.
+ """
+
+ project_id = proto.Field(proto.STRING, number=1)
+
+ dataset_id = proto.Field(proto.STRING, number=2)
+
+ model_id = proto.Field(proto.STRING, number=3)
+
+ model = proto.Field(proto.MESSAGE, number=4, message=Model,)
+
+
+class DeleteModelRequest(proto.Message):
+ r"""
+
+ Attributes:
+ project_id (str):
+ Required. Project ID of the model to delete.
+ dataset_id (str):
+ Required. Dataset ID of the model to delete.
+ model_id (str):
+ Required. Model ID of the model to delete.
+ """
+
+ project_id = proto.Field(proto.STRING, number=1)
+
+ dataset_id = proto.Field(proto.STRING, number=2)
+
+ model_id = proto.Field(proto.STRING, number=3)
+
+
+class ListModelsRequest(proto.Message):
+ r"""
+
+ Attributes:
+ project_id (str):
+ Required. Project ID of the models to list.
+ dataset_id (str):
+ Required. Dataset ID of the models to list.
+ max_results (~.wrappers.UInt32Value):
+ The maximum number of results to return in a
+ single response page. Leverage the page tokens
+ to iterate through the entire collection.
+ page_token (str):
+ Page token, returned by a previous call to
+ request the next page of results
+ """
+
+ project_id = proto.Field(proto.STRING, number=1)
+
+ dataset_id = proto.Field(proto.STRING, number=2)
+
+ max_results = proto.Field(proto.MESSAGE, number=3, message=wrappers.UInt32Value,)
+
+ page_token = proto.Field(proto.STRING, number=4)
+
+
+class ListModelsResponse(proto.Message):
+ r"""
+
+ Attributes:
+ models (Sequence[~.gcb_model.Model]):
+ Models in the requested dataset. Only the following fields
+ are populated: model_reference, model_type, creation_time,
+ last_modified_time and labels.
+ next_page_token (str):
+ A token to request the next page of results.
+ """
+
+ @property
+ def raw_page(self):
+ return self
+
+ models = proto.RepeatedField(proto.MESSAGE, number=1, message=Model,)
+
+ next_page_token = proto.Field(proto.STRING, number=2)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/bigquery_v2/types/model_reference.py b/google/cloud/bigquery_v2/types/model_reference.py
new file mode 100644
index 000000000..e3891d6c1
--- /dev/null
+++ b/google/cloud/bigquery_v2/types/model_reference.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import proto # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.bigquery.v2", manifest={"ModelReference",},
+)
+
+
+class ModelReference(proto.Message):
+ r"""Id path of a model.
+
+ Attributes:
+ project_id (str):
+ Required. The ID of the project containing
+ this model.
+ dataset_id (str):
+ Required. The ID of the dataset containing
+ this model.
+ model_id (str):
+ Required. The ID of the model. The ID must contain only
+ letters (a-z, A-Z), numbers (0-9), or underscores (_). The
+ maximum length is 1,024 characters.
+ """
+
+ project_id = proto.Field(proto.STRING, number=1)
+
+ dataset_id = proto.Field(proto.STRING, number=2)
+
+ model_id = proto.Field(proto.STRING, number=3)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/bigquery_v2/types/standard_sql.py b/google/cloud/bigquery_v2/types/standard_sql.py
new file mode 100644
index 000000000..72f12f284
--- /dev/null
+++ b/google/cloud/bigquery_v2/types/standard_sql.py
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import proto # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.bigquery.v2",
+ manifest={"StandardSqlDataType", "StandardSqlField", "StandardSqlStructType",},
+)
+
+
+class StandardSqlDataType(proto.Message):
+ r"""The type of a variable, e.g., a function argument. Examples: INT64:
+ {type_kind="INT64"} ARRAY: {type_kind="ARRAY",
+ array_element_type="STRING"} STRUCT:
+ {type_kind="STRUCT", struct_type={fields=[ {name="x",
+ type={type_kind="STRING"}}, {name="y", type={type_kind="ARRAY",
+ array_element_type="DATE"}} ]}}
+
+ Attributes:
+ type_kind (~.standard_sql.StandardSqlDataType.TypeKind):
+ Required. The top level type of this field.
+ Can be any standard SQL data type (e.g.,
+ "INT64", "DATE", "ARRAY").
+ array_element_type (~.standard_sql.StandardSqlDataType):
+ The type of the array's elements, if type_kind = "ARRAY".
+ struct_type (~.standard_sql.StandardSqlStructType):
+ The fields of this struct, in order, if type_kind =
+ "STRUCT".
+ """
+
+ class TypeKind(proto.Enum):
+ r""""""
+ TYPE_KIND_UNSPECIFIED = 0
+ INT64 = 2
+ BOOL = 5
+ FLOAT64 = 7
+ STRING = 8
+ BYTES = 9
+ TIMESTAMP = 19
+ DATE = 10
+ TIME = 20
+ DATETIME = 21
+ GEOGRAPHY = 22
+ NUMERIC = 23
+ ARRAY = 16
+ STRUCT = 17
+
+ type_kind = proto.Field(proto.ENUM, number=1, enum=TypeKind,)
+
+ array_element_type = proto.Field(
+ proto.MESSAGE, number=2, oneof="sub_type", message="StandardSqlDataType",
+ )
+
+ struct_type = proto.Field(
+ proto.MESSAGE, number=3, oneof="sub_type", message="StandardSqlStructType",
+ )
+
+
+class StandardSqlField(proto.Message):
+ r"""A field or a column.
+
+ Attributes:
+ name (str):
+ Optional. The name of this field. Can be
+ absent for struct fields.
+ type (~.standard_sql.StandardSqlDataType):
+ Optional. The type of this parameter. Absent
+ if not explicitly specified (e.g., CREATE
+ FUNCTION statement can omit the return type; in
+ this case the output parameter does not have
+ this "type" field).
+ """
+
+ name = proto.Field(proto.STRING, number=1)
+
+ type = proto.Field(proto.MESSAGE, number=2, message=StandardSqlDataType,)
+
+
+class StandardSqlStructType(proto.Message):
+ r"""
+
+ Attributes:
+ fields (Sequence[~.standard_sql.StandardSqlField]):
+
+ """
+
+ fields = proto.RepeatedField(proto.MESSAGE, number=1, message=StandardSqlField,)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/noxfile.py b/noxfile.py
index 90f023add..42d8f9356 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -49,16 +49,10 @@ def default(session):
constraints_path,
)
- if session.python == "2.7":
- # The [all] extra is not installable on Python 2.7.
- session.install("-e", ".[pandas,pyarrow]", "-c", constraints_path)
- elif session.python == "3.5":
- session.install("-e", ".[all]", "-c", constraints_path)
- else:
- # fastparquet is not included in .[all] because, in general, it's
- # redundant with pyarrow. We still want to run some unit tests with
- # fastparquet serialization, though.
- session.install("-e", ".[all,fastparquet]", "-c", constraints_path)
+ # fastparquet is not included in .[all] because, in general, it's
+ # redundant with pyarrow. We still want to run some unit tests with
+ # fastparquet serialization, though.
+ session.install("-e", ".[all,fastparquet]", "-c", constraints_path)
session.install("ipython", "-c", constraints_path)
@@ -77,13 +71,13 @@ def default(session):
)
-@nox.session(python=["2.7", "3.5", "3.6", "3.7", "3.8"])
+@nox.session(python=["3.6", "3.7", "3.8"])
def unit(session):
"""Run the unit test suite."""
default(session)
-@nox.session(python=["2.7", "3.8"])
+@nox.session(python=["3.8"])
def system(session):
"""Run the system test suite."""
@@ -108,12 +102,7 @@ def system(session):
)
session.install("google-cloud-storage", "-c", constraints_path)
- if session.python == "2.7":
- # The [all] extra is not installable on Python 2.7.
- session.install("-e", ".[pandas]", "-c", constraints_path)
- else:
- session.install("-e", ".[all]", "-c", constraints_path)
-
+ session.install("-e", ".[all]", "-c", constraints_path)
session.install("ipython", "-c", constraints_path)
# Run py.test against the system tests.
@@ -122,7 +111,7 @@ def system(session):
)
-@nox.session(python=["2.7", "3.8"])
+@nox.session(python=["3.8"])
def snippets(session):
"""Run the snippets test suite."""
@@ -139,11 +128,7 @@ def snippets(session):
session.install("google-cloud-storage", "-c", constraints_path)
session.install("grpcio", "-c", constraints_path)
- if session.python == "2.7":
- # The [all] extra is not installable on Python 2.7.
- session.install("-e", ".[pandas]", "-c", constraints_path)
- else:
- session.install("-e", ".[all]", "-c", constraints_path)
+ session.install("-e", ".[all]", "-c", constraints_path)
# Run py.test against the snippets tests.
# Skip tests in samples/snippets, as those are run in a different session
diff --git a/samples/create_routine.py b/samples/create_routine.py
index d9b221a4f..012c7927a 100644
--- a/samples/create_routine.py
+++ b/samples/create_routine.py
@@ -34,7 +34,7 @@ def create_routine(routine_id):
bigquery.RoutineArgument(
name="x",
data_type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
),
)
],
diff --git a/samples/tests/conftest.py b/samples/tests/conftest.py
index d80085dd3..0fdacaaec 100644
--- a/samples/tests/conftest.py
+++ b/samples/tests/conftest.py
@@ -126,7 +126,7 @@ def routine_id(client, dataset_id):
bigquery.RoutineArgument(
name="x",
data_type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
),
)
]
diff --git a/samples/tests/test_routine_samples.py b/samples/tests/test_routine_samples.py
index a4467c59a..59ec1fae9 100644
--- a/samples/tests/test_routine_samples.py
+++ b/samples/tests/test_routine_samples.py
@@ -39,21 +39,21 @@ def test_create_routine_ddl(capsys, random_routine_id, client):
bigquery.RoutineArgument(
name="arr",
data_type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.ARRAY,
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.ARRAY,
array_element_type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.STRUCT,
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.STRUCT,
struct_type=bigquery_v2.types.StandardSqlStructType(
fields=[
bigquery_v2.types.StandardSqlField(
name="name",
type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.STRING
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.STRING
),
),
bigquery_v2.types.StandardSqlField(
name="val",
type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
),
),
]
diff --git a/scripts/fixup_bigquery_v2_keywords.py b/scripts/fixup_bigquery_v2_keywords.py
new file mode 100644
index 000000000..82b46d64e
--- /dev/null
+++ b/scripts/fixup_bigquery_v2_keywords.py
@@ -0,0 +1,181 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import argparse
+import os
+import libcst as cst
+import pathlib
+import sys
+from typing import (Any, Callable, Dict, List, Sequence, Tuple)
+
+
+def partition(
+ predicate: Callable[[Any], bool],
+ iterator: Sequence[Any]
+) -> Tuple[List[Any], List[Any]]:
+ """A stable, out-of-place partition."""
+ results = ([], [])
+
+ for i in iterator:
+ results[int(predicate(i))].append(i)
+
+ # Returns trueList, falseList
+ return results[1], results[0]
+
+
+class bigqueryCallTransformer(cst.CSTTransformer):
+ CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata')
+ METHOD_TO_PARAMS: Dict[str, Tuple[str]] = {
+ 'delete_model': ('project_id', 'dataset_id', 'model_id', ),
+ 'get_model': ('project_id', 'dataset_id', 'model_id', ),
+ 'list_models': ('project_id', 'dataset_id', 'max_results', 'page_token', ),
+ 'patch_model': ('project_id', 'dataset_id', 'model_id', 'model', ),
+
+ }
+
+ def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode:
+ try:
+ key = original.func.attr.value
+ kword_params = self.METHOD_TO_PARAMS[key]
+ except (AttributeError, KeyError):
+ # Either not a method from the API or too convoluted to be sure.
+ return updated
+
+ # If the existing code is valid, keyword args come after positional args.
+ # Therefore, all positional args must map to the first parameters.
+ args, kwargs = partition(lambda a: not bool(a.keyword), updated.args)
+ if any(k.keyword.value == "request" for k in kwargs):
+ # We've already fixed this file, don't fix it again.
+ return updated
+
+ kwargs, ctrl_kwargs = partition(
+ lambda a: not a.keyword.value in self.CTRL_PARAMS,
+ kwargs
+ )
+
+ args, ctrl_args = args[:len(kword_params)], args[len(kword_params):]
+ ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl))
+ for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS))
+
+ request_arg = cst.Arg(
+ value=cst.Dict([
+ cst.DictElement(
+ cst.SimpleString("'{}'".format(name)),
+ cst.Element(value=arg.value)
+ )
+ # Note: the args + kwargs looks silly, but keep in mind that
+ # the control parameters had to be stripped out, and that
+ # those could have been passed positionally or by keyword.
+ for name, arg in zip(kword_params, args + kwargs)]),
+ keyword=cst.Name("request")
+ )
+
+ return updated.with_changes(
+ args=[request_arg] + ctrl_kwargs
+ )
+
+
+def fix_files(
+ in_dir: pathlib.Path,
+ out_dir: pathlib.Path,
+ *,
+ transformer=bigqueryCallTransformer(),
+):
+ """Duplicate the input dir to the output dir, fixing file method calls.
+
+ Preconditions:
+ * in_dir is a real directory
+ * out_dir is a real, empty directory
+ """
+ pyfile_gen = (
+ pathlib.Path(os.path.join(root, f))
+ for root, _, files in os.walk(in_dir)
+ for f in files if os.path.splitext(f)[1] == ".py"
+ )
+
+ for fpath in pyfile_gen:
+ with open(fpath, 'r') as f:
+ src = f.read()
+
+ # Parse the code and insert method call fixes.
+ tree = cst.parse_module(src)
+ updated = tree.visit(transformer)
+
+ # Create the path and directory structure for the new file.
+ updated_path = out_dir.joinpath(fpath.relative_to(in_dir))
+ updated_path.parent.mkdir(parents=True, exist_ok=True)
+
+ # Generate the updated source file at the corresponding path.
+ with open(updated_path, 'w') as f:
+ f.write(updated.code)
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(
+ description="""Fix up source that uses the bigquery client library.
+
+The existing sources are NOT overwritten but are copied to output_dir with changes made.
+
+Note: This tool operates at a best-effort level at converting positional
+ parameters in client method calls to keyword based parameters.
+ Cases where it WILL FAIL include
+ A) * or ** expansion in a method call.
+ B) Calls via function or method alias (includes free function calls)
+ C) Indirect or dispatched calls (e.g. the method is looked up dynamically)
+
+ These all constitute false negatives. The tool will also detect false
+ positives when an API method shares a name with another method.
+""")
+ parser.add_argument(
+ '-d',
+ '--input-directory',
+ required=True,
+ dest='input_dir',
+ help='the input directory to walk for python files to fix up',
+ )
+ parser.add_argument(
+ '-o',
+ '--output-directory',
+ required=True,
+ dest='output_dir',
+ help='the directory to output files fixed via un-flattening',
+ )
+ args = parser.parse_args()
+ input_dir = pathlib.Path(args.input_dir)
+ output_dir = pathlib.Path(args.output_dir)
+ if not input_dir.is_dir():
+ print(
+ f"input directory '{input_dir}' does not exist or is not a directory",
+ file=sys.stderr,
+ )
+ sys.exit(-1)
+
+ if not output_dir.is_dir():
+ print(
+ f"output directory '{output_dir}' does not exist or is not a directory",
+ file=sys.stderr,
+ )
+ sys.exit(-1)
+
+ if os.listdir(output_dir):
+ print(
+ f"output directory '{output_dir}' is not empty",
+ file=sys.stderr,
+ )
+ sys.exit(-1)
+
+ fix_files(input_dir, output_dir)
diff --git a/setup.py b/setup.py
index 73d9a03ca..2cb57aad2 100644
--- a/setup.py
+++ b/setup.py
@@ -22,22 +22,23 @@
name = "google-cloud-bigquery"
description = "Google BigQuery API client library"
-version = "1.28.0"
+version = "2.0.0"
# Should be one of:
# 'Development Status :: 3 - Alpha'
# 'Development Status :: 4 - Beta'
# 'Development Status :: 5 - Production/Stable'
release_status = "Development Status :: 5 - Production/Stable"
dependencies = [
- 'enum34; python_version < "3.4"',
- "google-api-core >= 1.21.0, < 2.0dev",
+ "google-api-core[grpc] >= 1.22.2, < 2.0.0dev",
+ "proto-plus >= 1.10.0",
+ "libcst >= 0.2.5",
"google-cloud-core >= 1.4.1, < 2.0dev",
"google-resumable-media >= 0.6.0, < 2.0dev",
"six >=1.13.0,< 2.0.0dev",
]
extras = {
"bqstorage": [
- "google-cloud-bigquery-storage >= 1.0.0, <2.0.0dev",
+ "google-cloud-bigquery-storage >= 2.0.0, <3.0.0dev",
# Due to an issue in pip's dependency resolver, the `grpc` extra is not
# installed, even though `google-cloud-bigquery-storage` specifies it
# as `google-api-core[grpc]`. We thus need to explicitly specify it here.
@@ -50,19 +51,10 @@
"pandas": ["pandas>=0.23.0"],
"pyarrow": [
# pyarrow 1.0.0 is required for the use of timestamp_as_object keyword.
- "pyarrow >= 1.0.0, < 2.0de ; python_version>='3.5'",
- "pyarrow >= 0.16.0, < 0.17.0dev ; python_version<'3.5'",
+ "pyarrow >= 1.0.0, < 2.0dev",
],
"tqdm": ["tqdm >= 4.7.4, <5.0.0dev"],
- "fastparquet": [
- "fastparquet",
- "python-snappy",
- # llvmlite >= 0.32.0 cannot be installed on Python 3.5 and below
- # (building the wheel fails), thus needs to be restricted.
- # See: https://github.com/googleapis/python-bigquery/issues/78
- "llvmlite<=0.34.0;python_version>='3.6'",
- "llvmlite<=0.31.0;python_version<'3.6'",
- ],
+ "fastparquet": ["fastparquet", "python-snappy", "llvmlite>=0.34.0"],
"opentelemetry": [
"opentelemetry-api==0.9b0",
"opentelemetry-sdk==0.9b0",
@@ -95,7 +87,9 @@
# Only include packages under the 'google' namespace. Do not include tests,
# benchmarks, etc.
packages = [
- package for package in setuptools.find_packages() if package.startswith("google")
+ package
+ for package in setuptools.PEP420PackageFinder.find()
+ if package.startswith("google")
]
# Determine which namespaces are needed.
@@ -118,10 +112,7 @@
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
@@ -133,7 +124,8 @@
namespace_packages=namespaces,
install_requires=dependencies,
extras_require=extras,
- python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*",
+ python_requires=">=3.6",
+ scripts=["scripts/fixup_bigquery_v2_keywords.py"],
include_package_data=True,
zip_safe=False,
)
diff --git a/synth.metadata b/synth.metadata
index 7fdc4fb28..c47ff1e51 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -3,30 +3,15 @@
{
"git": {
"name": ".",
- "remote": "https://github.com/googleapis/python-bigquery.git",
- "sha": "b716e1c8ecd90142b498b95e7f8830835529cf4a"
- }
- },
- {
- "git": {
- "name": "googleapis",
- "remote": "https://github.com/googleapis/googleapis.git",
- "sha": "0dc0a6c0f1a9f979bc0690f0caa5fbafa3000c2c",
- "internalRef": "327026955"
+ "remote": "git@github.com:plamut/python-bigquery.git",
+ "sha": "64d666033446f9af669bb8eb9170b8f62d6308e4"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "27f4406999b1eee29e04b09b2423a8e4646c7e24"
- }
- },
- {
- "git": {
- "name": "synthtool",
- "remote": "https://github.com/googleapis/synthtool.git",
- "sha": "27f4406999b1eee29e04b09b2423a8e4646c7e24"
+ "sha": "8a7a3021fe97aa0a3641db642fe2b767f1c8110f"
}
}
],
@@ -40,89 +25,5 @@
"generator": "bazel"
}
}
- ],
- "generatedFiles": [
- ".coveragerc",
- ".flake8",
- ".github/CONTRIBUTING.md",
- ".github/ISSUE_TEMPLATE/bug_report.md",
- ".github/ISSUE_TEMPLATE/feature_request.md",
- ".github/ISSUE_TEMPLATE/support_request.md",
- ".github/PULL_REQUEST_TEMPLATE.md",
- ".github/release-please.yml",
- ".github/snippet-bot.yml",
- ".gitignore",
- ".kokoro/build.sh",
- ".kokoro/continuous/common.cfg",
- ".kokoro/continuous/continuous.cfg",
- ".kokoro/docker/docs/Dockerfile",
- ".kokoro/docker/docs/fetch_gpg_keys.sh",
- ".kokoro/docs/common.cfg",
- ".kokoro/docs/docs-presubmit.cfg",
- ".kokoro/docs/docs.cfg",
- ".kokoro/populate-secrets.sh",
- ".kokoro/presubmit/common.cfg",
- ".kokoro/presubmit/presubmit.cfg",
- ".kokoro/presubmit/system-2.7.cfg",
- ".kokoro/presubmit/system-3.8.cfg",
- ".kokoro/publish-docs.sh",
- ".kokoro/release.sh",
- ".kokoro/release/common.cfg",
- ".kokoro/release/release.cfg",
- ".kokoro/samples/lint/common.cfg",
- ".kokoro/samples/lint/continuous.cfg",
- ".kokoro/samples/lint/periodic.cfg",
- ".kokoro/samples/lint/presubmit.cfg",
- ".kokoro/samples/python3.6/common.cfg",
- ".kokoro/samples/python3.6/continuous.cfg",
- ".kokoro/samples/python3.6/periodic.cfg",
- ".kokoro/samples/python3.6/presubmit.cfg",
- ".kokoro/samples/python3.7/common.cfg",
- ".kokoro/samples/python3.7/continuous.cfg",
- ".kokoro/samples/python3.7/periodic.cfg",
- ".kokoro/samples/python3.7/presubmit.cfg",
- ".kokoro/samples/python3.8/common.cfg",
- ".kokoro/samples/python3.8/continuous.cfg",
- ".kokoro/samples/python3.8/periodic.cfg",
- ".kokoro/samples/python3.8/presubmit.cfg",
- ".kokoro/test-samples.sh",
- ".kokoro/trampoline.sh",
- ".kokoro/trampoline_v2.sh",
- ".trampolinerc",
- "CODE_OF_CONDUCT.md",
- "CONTRIBUTING.rst",
- "LICENSE",
- "MANIFEST.in",
- "docs/_static/custom.css",
- "docs/_templates/layout.html",
- "docs/conf.py",
- "google/cloud/bigquery_v2/gapic/enums.py",
- "google/cloud/bigquery_v2/proto/encryption_config.proto",
- "google/cloud/bigquery_v2/proto/encryption_config_pb2.py",
- "google/cloud/bigquery_v2/proto/encryption_config_pb2_grpc.py",
- "google/cloud/bigquery_v2/proto/model.proto",
- "google/cloud/bigquery_v2/proto/model_pb2.py",
- "google/cloud/bigquery_v2/proto/model_pb2_grpc.py",
- "google/cloud/bigquery_v2/proto/model_reference.proto",
- "google/cloud/bigquery_v2/proto/model_reference_pb2.py",
- "google/cloud/bigquery_v2/proto/model_reference_pb2_grpc.py",
- "google/cloud/bigquery_v2/proto/standard_sql.proto",
- "google/cloud/bigquery_v2/proto/standard_sql_pb2.py",
- "google/cloud/bigquery_v2/proto/standard_sql_pb2_grpc.py",
- "google/cloud/bigquery_v2/types.py",
- "renovate.json",
- "samples/AUTHORING_GUIDE.md",
- "samples/CONTRIBUTING.md",
- "samples/snippets/README.rst",
- "samples/snippets/noxfile.py",
- "scripts/decrypt-secrets.sh",
- "scripts/readme-gen/readme_gen.py",
- "scripts/readme-gen/templates/README.tmpl.rst",
- "scripts/readme-gen/templates/auth.tmpl.rst",
- "scripts/readme-gen/templates/auth_api_key.tmpl.rst",
- "scripts/readme-gen/templates/install_deps.tmpl.rst",
- "scripts/readme-gen/templates/install_portaudio.tmpl.rst",
- "setup.cfg",
- "testing/.gitignore"
]
}
\ No newline at end of file
diff --git a/synth.py b/synth.py
index ac20c9aec..501380be2 100644
--- a/synth.py
+++ b/synth.py
@@ -20,56 +20,73 @@
gapic = gcp.GAPICBazel()
common = gcp.CommonTemplates()
-version = 'v2'
+version = "v2"
library = gapic.py_library(
- service='bigquery',
+ service="bigquery",
version=version,
bazel_target=f"//google/cloud/bigquery/{version}:bigquery-{version}-py",
include_protos=True,
)
s.move(
- [
- library / "google/cloud/bigquery_v2/gapic/enums.py",
- library / "google/cloud/bigquery_v2/types.py",
- library / "google/cloud/bigquery_v2/proto/location*",
- library / "google/cloud/bigquery_v2/proto/encryption_config*",
- library / "google/cloud/bigquery_v2/proto/model*",
- library / "google/cloud/bigquery_v2/proto/standard_sql*",
+ library,
+ excludes=[
+ "docs/index.rst",
+ "README.rst",
+ "noxfile.py",
+ "setup.py",
+ library / f"google/cloud/bigquery/__init__.py",
+ library / f"google/cloud/bigquery/py.typed",
+ # There are no public API endpoints for the generated ModelServiceClient,
+ # thus there's no point in generating it and its tests.
+ library / f"google/cloud/bigquery_{version}/services/**",
+ library / f"tests/unit/gapic/bigquery_{version}/**",
],
)
-# Fix up proto docs that are missing summary line.
-s.replace(
- "google/cloud/bigquery_v2/proto/model_pb2.py",
- '"""Attributes:',
- '"""Protocol buffer.\n\n Attributes:',
-)
-s.replace(
- "google/cloud/bigquery_v2/proto/encryption_config_pb2.py",
- '"""Attributes:',
- '"""Encryption configuration.\n\n Attributes:',
-)
-
-# Remove non-ascii characters from docstrings for Python 2.7.
-# Format quoted strings as plain text.
-s.replace("google/cloud/bigquery_v2/proto/*.py", "[“”]", '``')
-
# ----------------------------------------------------------------------------
# Add templated files
# ----------------------------------------------------------------------------
-templated_files = common.py_library(cov_level=100, samples=True, split_system_tests=True)
+templated_files = common.py_library(
+ cov_level=100,
+ samples=True,
+ microgenerator=True,
+ split_system_tests=True,
+)
# BigQuery has a custom multiprocessing note
-s.move(templated_files, excludes=["noxfile.py", "docs/multiprocessing.rst"])
+s.move(
+ templated_files,
+ excludes=["noxfile.py", "docs/multiprocessing.rst", ".coveragerc"]
+)
# ----------------------------------------------------------------------------
# Samples templates
# ----------------------------------------------------------------------------
-python.py_samples()
+# python.py_samples() # TODO: why doesn't this work here with Bazel?
+
+# Do not expose ModelServiceClient, as there is no public API endpoint for the
+# models service.
+s.replace(
+ "google/cloud/bigquery_v2/__init__.py",
+ r"from \.services\.model_service import ModelServiceClient",
+ "",
+)
+s.replace(
+ "google/cloud/bigquery_v2/__init__.py",
+ r"""["']ModelServiceClient["'],""",
+ "",
+)
+# Adjust Model docstring so that Sphinx does not think that "predicted_" is
+# a reference to something, issuing a false warning.
+s.replace(
+ "google/cloud/bigquery_v2/types/model.py",
+ r'will have a "predicted_"',
+ "will have a `predicted_`",
+)
s.replace(
"docs/conf.py",
@@ -77,4 +94,11 @@
'{"members": True, "inherited-members": True}'
)
+# Tell Sphinx to ingore autogenerated docs files.
+s.replace(
+ "docs/conf.py",
+ r'"samples/snippets/README\.rst",',
+ '\g<0>\n "bigquery_v2/services.rst", # generated by the code generator',
+)
+
s.shell.run(["nox", "-s", "blacken"], hide_output=False)
diff --git a/testing/constraints-2.7.txt b/testing/constraints-2.7.txt
deleted file mode 100644
index fafbaa27f..000000000
--- a/testing/constraints-2.7.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-google-api-core==1.21.0
-google-cloud-core==1.4.1
-google-cloud-storage==1.30.0
-google-resumable-media==0.6.0
-ipython==5.5
-pandas==0.23.0
-pyarrow==0.16.0
-six==1.13.0
-tqdm==4.7.4
\ No newline at end of file
diff --git a/testing/constraints-3.5.txt b/testing/constraints-3.5.txt
deleted file mode 100644
index a262dbe5f..000000000
--- a/testing/constraints-3.5.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-google-api-core==1.21.0
-google-cloud-bigquery-storage==1.0.0
-google-cloud-core==1.4.1
-google-resumable-media==0.6.0
-google-cloud-storage==1.30.0
-grpcio==1.32.0
-ipython==5.5
-# pandas 0.23.0 is the first version to work with pyarrow to_pandas.
-pandas==0.23.0
-pyarrow==1.0.0
-six==1.13.0
-tqdm==4.7.4
\ No newline at end of file
diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt
index e69de29bb..a9f4faa92 100644
--- a/testing/constraints-3.6.txt
+++ b/testing/constraints-3.6.txt
@@ -0,0 +1,16 @@
+fastparquet==0.4.1
+google-api-core==1.22.2
+google-cloud-bigquery-storage==2.0.0
+google-cloud-core==1.4.1
+google-resumable-media==0.6.0
+grpcio==1.32.0
+ipython==5.5
+libcst==0.2.5
+llvmlite==0.34.0
+# pandas 0.23.0 is the first version to work with pyarrow to_pandas.
+pandas==0.23.0
+proto-plus==1.10.0
+pyarrow==1.0.0
+python-snappy==0.5.4
+six==1.13.0
+tqdm==4.7.4
diff --git a/tests/system.py b/tests/system.py
index 02cc8e139..68fcb918c 100644
--- a/tests/system.py
+++ b/tests/system.py
@@ -34,11 +34,9 @@
import pkg_resources
try:
- from google.cloud import bigquery_storage_v1
- from google.cloud import bigquery_storage_v1beta1
+ from google.cloud import bigquery_storage
except ImportError: # pragma: NO COVER
- bigquery_storage_v1 = None
- bigquery_storage_v1beta1 = None
+ bigquery_storage = None
try:
import fastavro # to parse BQ storage client results
@@ -1793,57 +1791,11 @@ def test_dbapi_fetchall(self):
self.assertEqual(row_tuples, [(1, 2), (3, 4), (5, 6)])
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_dbapi_fetch_w_bqstorage_client_large_result_set(self):
- bqstorage_client = bigquery_storage_v1.BigQueryReadClient(
- credentials=Config.CLIENT._credentials
- )
- cursor = dbapi.connect(Config.CLIENT, bqstorage_client).cursor()
-
- cursor.execute(
- """
- SELECT id, `by`, time_ts
- FROM `bigquery-public-data.hacker_news.comments`
- ORDER BY `id` ASC
- LIMIT 100000
- """
- )
-
- result_rows = [cursor.fetchone(), cursor.fetchone(), cursor.fetchone()]
-
- field_name = operator.itemgetter(0)
- fetched_data = [sorted(row.items(), key=field_name) for row in result_rows]
-
- # Since DB API is not thread safe, only a single result stream should be
- # requested by the BQ storage client, meaning that results should arrive
- # in the sorted order.
- expected_data = [
- [
- ("by", "sama"),
- ("id", 15),
- ("time_ts", datetime.datetime(2006, 10, 9, 19, 51, 1, tzinfo=UTC)),
- ],
- [
- ("by", "pg"),
- ("id", 17),
- ("time_ts", datetime.datetime(2006, 10, 9, 19, 52, 45, tzinfo=UTC)),
- ],
- [
- ("by", "pg"),
- ("id", 22),
- ("time_ts", datetime.datetime(2006, 10, 10, 2, 18, 22, tzinfo=UTC)),
- ],
- ]
- self.assertEqual(fetched_data, expected_data)
-
- @unittest.skipIf(
- bigquery_storage_v1beta1 is None, "Requires `google-cloud-bigquery-storage`"
- )
- @unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
- def test_dbapi_fetch_w_bqstorage_client_v1beta1_large_result_set(self):
- bqstorage_client = bigquery_storage_v1beta1.BigQueryStorageClient(
+ bqstorage_client = bigquery_storage.BigQueryReadClient(
credentials=Config.CLIENT._credentials
)
cursor = dbapi.connect(Config.CLIENT, bqstorage_client).cursor()
@@ -1901,7 +1853,7 @@ def test_dbapi_dry_run_query(self):
self.assertEqual(list(rows), [])
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_dbapi_connection_does_not_leak_sockets(self):
current_process = psutil.Process()
@@ -2331,7 +2283,7 @@ def test_query_results_to_dataframe(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_query_results_to_dataframe_w_bqstorage(self):
query = """
@@ -2340,40 +2292,7 @@ def test_query_results_to_dataframe_w_bqstorage(self):
LIMIT 10
"""
- bqstorage_client = bigquery_storage_v1.BigQueryReadClient(
- credentials=Config.CLIENT._credentials
- )
-
- df = Config.CLIENT.query(query).result().to_dataframe(bqstorage_client)
-
- self.assertIsInstance(df, pandas.DataFrame)
- self.assertEqual(len(df), 10) # verify the number of rows
- column_names = ["id", "author", "time_ts", "dead"]
- self.assertEqual(list(df), column_names)
- exp_datatypes = {
- "id": int,
- "author": six.text_type,
- "time_ts": pandas.Timestamp,
- "dead": bool,
- }
- for index, row in df.iterrows():
- for col in column_names:
- # all the schema fields are nullable, so None is acceptable
- if not row[col] is None:
- self.assertIsInstance(row[col], exp_datatypes[col])
-
- @unittest.skipIf(pandas is None, "Requires `pandas`")
- @unittest.skipIf(
- bigquery_storage_v1beta1 is None, "Requires `google-cloud-bigquery-storage`"
- )
- def test_query_results_to_dataframe_w_bqstorage_v1beta1(self):
- query = """
- SELECT id, author, time_ts, dead
- FROM `bigquery-public-data.hacker_news.comments`
- LIMIT 10
- """
-
- bqstorage_client = bigquery_storage_v1beta1.BigQueryStorageClient(
+ bqstorage_client = bigquery_storage.BigQueryReadClient(
credentials=Config.CLIENT._credentials
)
@@ -2569,7 +2488,7 @@ def test_create_routine(self):
routine_name = "test_routine"
dataset = self.temp_dataset(_make_dataset_id("create_routine"))
float64_type = bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.FLOAT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.FLOAT64
)
routine = bigquery.Routine(
dataset.routine(routine_name),
@@ -2584,7 +2503,7 @@ def test_create_routine(self):
bigquery.RoutineArgument(
name="arr",
data_type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.ARRAY,
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.ARRAY,
array_element_type=float64_type,
),
)
@@ -2663,7 +2582,7 @@ def _fetch_dataframe(self, query):
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_nested_table_to_arrow(self):
from google.cloud.bigquery.job import SourceFormat
@@ -2699,7 +2618,7 @@ def test_nested_table_to_arrow(self):
job_config.schema = schema
# Load a table using a local JSON file from memory.
Config.CLIENT.load_table_from_file(body, table, job_config=job_config).result()
- bqstorage_client = bigquery_storage_v1.BigQueryReadClient(
+ bqstorage_client = bigquery_storage.BigQueryReadClient(
credentials=Config.CLIENT._credentials
)
@@ -2855,13 +2774,13 @@ def test_list_rows_page_size(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_list_rows_max_results_w_bqstorage(self):
table_ref = DatasetReference("bigquery-public-data", "utility_us").table(
"country_code_iso"
)
- bqstorage_client = bigquery_storage_v1.BigQueryReadClient(
+ bqstorage_client = bigquery_storage.BigQueryReadClient(
credentials=Config.CLIENT._credentials
)
diff --git a/tests/unit/enums/test_standard_sql_data_types.py b/tests/unit/enums/test_standard_sql_data_types.py
index 6fa4f057f..7f62c46fd 100644
--- a/tests/unit/enums/test_standard_sql_data_types.py
+++ b/tests/unit/enums/test_standard_sql_data_types.py
@@ -32,7 +32,7 @@ def enum_under_test():
@pytest.fixture
def gapic_enum():
"""The referential autogenerated enum the enum under test is based on."""
- from google.cloud.bigquery_v2.gapic.enums import StandardSqlDataType
+ from google.cloud.bigquery_v2.types import StandardSqlDataType
return StandardSqlDataType.TypeKind
@@ -61,7 +61,10 @@ def test_standard_sql_types_enum_members(enum_under_test, gapic_enum):
assert name not in enum_under_test.__members__
-def test_standard_sql_types_enum_docstring(enum_under_test, gapic_enum):
+@pytest.mark.skip(reason="Code generator issue, the docstring is not generated.")
+def test_standard_sql_types_enum_docstring(
+ enum_under_test, gapic_enum
+): # pragma: NO COVER
assert "STRUCT (int):" not in enum_under_test.__doc__
assert "BOOL (int):" in enum_under_test.__doc__
assert "TIME (int):" in enum_under_test.__doc__
diff --git a/tests/unit/model/test_model.py b/tests/unit/model/test_model.py
index 90fc09e66..2c0079429 100644
--- a/tests/unit/model/test_model.py
+++ b/tests/unit/model/test_model.py
@@ -19,7 +19,7 @@
import pytest
import google.cloud._helpers
-from google.cloud.bigquery_v2.gapic import enums
+from google.cloud.bigquery_v2 import types
KMS_KEY_NAME = "projects/1/locations/us/keyRings/1/cryptoKeys/1"
@@ -117,7 +117,7 @@ def test_from_api_repr(target_class):
assert got.expires == expiration_time
assert got.description == u"A friendly description."
assert got.friendly_name == u"A friendly name."
- assert got.model_type == enums.Model.ModelType.LOGISTIC_REGRESSION
+ assert got.model_type == types.Model.ModelType.LOGISTIC_REGRESSION
assert got.labels == {"greeting": u"こんにちは"}
assert got.encryption_configuration.kms_key_name == KMS_KEY_NAME
assert got.training_runs[0].training_options.initial_learn_rate == 1.0
@@ -162,7 +162,7 @@ def test_from_api_repr_w_minimal_resource(target_class):
assert got.expires is None
assert got.description is None
assert got.friendly_name is None
- assert got.model_type == enums.Model.ModelType.MODEL_TYPE_UNSPECIFIED
+ assert got.model_type == types.Model.ModelType.MODEL_TYPE_UNSPECIFIED
assert got.labels == {}
assert got.encryption_configuration is None
assert len(got.training_runs) == 0
diff --git a/tests/unit/routine/test_routine.py b/tests/unit/routine/test_routine.py
index 02f703535..b02ace1db 100644
--- a/tests/unit/routine/test_routine.py
+++ b/tests/unit/routine/test_routine.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright 2019 Google LLC
#
@@ -63,14 +62,14 @@ def test_ctor_w_properties(target_class):
RoutineArgument(
name="x",
data_type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
),
)
]
body = "x * 3"
language = "SQL"
return_type = bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
)
type_ = "SCALAR_FUNCTION"
description = "A routine description."
@@ -141,14 +140,14 @@ def test_from_api_repr(target_class):
RoutineArgument(
name="x",
data_type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
),
)
]
assert actual_routine.body == "42"
assert actual_routine.language == "SQL"
assert actual_routine.return_type == bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
)
assert actual_routine.type_ == "SCALAR_FUNCTION"
assert actual_routine._properties["someNewField"] == "someValue"
diff --git a/tests/unit/routine/test_routine_argument.py b/tests/unit/routine/test_routine_argument.py
index 7d17b5fc7..e3bda9539 100644
--- a/tests/unit/routine/test_routine_argument.py
+++ b/tests/unit/routine/test_routine_argument.py
@@ -28,7 +28,7 @@ def target_class():
def test_ctor(target_class):
data_type = bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
)
actual_arg = target_class(
name="field_name", kind="FIXED_TYPE", mode="IN", data_type=data_type
@@ -51,7 +51,7 @@ def test_from_api_repr(target_class):
assert actual_arg.kind == "FIXED_TYPE"
assert actual_arg.mode == "IN"
assert actual_arg.data_type == bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
)
@@ -72,7 +72,7 @@ def test_from_api_repr_w_unknown_fields(target_class):
def test_eq(target_class):
data_type = bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
)
arg = target_class(
name="field_name", kind="FIXED_TYPE", mode="IN", data_type=data_type
diff --git a/tests/unit/test__pandas_helpers.py b/tests/unit/test__pandas_helpers.py
index f4355072a..c1073066d 100644
--- a/tests/unit/test__pandas_helpers.py
+++ b/tests/unit/test__pandas_helpers.py
@@ -20,7 +20,6 @@
import warnings
import mock
-import six
try:
import pandas
@@ -300,10 +299,7 @@ def test_bq_to_arrow_data_type_w_struct(module_under_test, bq_type):
)
)
assert pyarrow.types.is_struct(actual)
- try:
- assert actual.num_fields == len(fields)
- except AttributeError: # py27
- assert actual.num_children == len(fields)
+ assert actual.num_fields == len(fields)
assert actual.equals(expected)
@@ -348,10 +344,7 @@ def test_bq_to_arrow_data_type_w_array_struct(module_under_test, bq_type):
)
assert pyarrow.types.is_list(actual)
assert pyarrow.types.is_struct(actual.value_type)
- try:
- assert actual.value_type.num_fields == len(fields)
- except AttributeError: # py27
- assert actual.value_type.num_children == len(fields)
+ assert actual.value_type.num_fields == len(fields)
assert actual.value_type.equals(expected_value_type)
@@ -553,12 +546,9 @@ def test_bq_to_arrow_schema_w_unknown_type(module_under_test):
actual = module_under_test.bq_to_arrow_schema(fields)
assert actual is None
- if six.PY3:
- assert len(warned) == 1
- warning = warned[0]
- assert "field3" in str(warning)
- else:
- assert len(warned) == 0
+ assert len(warned) == 1
+ warning = warned[0]
+ assert "field3" in str(warning)
@pytest.mark.skipif(pandas is None, reason="Requires `pandas`")
@@ -773,26 +763,6 @@ def test_dataframe_to_bq_schema_dict_sequence(module_under_test):
assert returned_schema == expected_schema
-@pytest.mark.skipif(pandas is None, reason="Requires `pandas`")
-@pytest.mark.skipif(not six.PY2, reason="Requires Python 2.7")
-def test_dataframe_to_bq_schema_w_struct_raises_py27(module_under_test):
- dataframe = pandas.DataFrame(
- data=[{"struct_field": {"int_col": 1}}, {"struct_field": {"int_col": 2}}]
- )
- bq_schema = [
- schema.SchemaField(
- "struct_field",
- field_type="STRUCT",
- fields=[schema.SchemaField("int_col", field_type="INT64")],
- ),
- ]
-
- with pytest.raises(ValueError) as excinfo:
- module_under_test.dataframe_to_bq_schema(dataframe, bq_schema=bq_schema)
-
- assert "struct (record) column types is not supported" in str(excinfo.value)
-
-
@pytest.mark.skipif(pandas is None, reason="Requires `pandas`")
@pytest.mark.skipif(isinstance(pyarrow, mock.Mock), reason="Requires `pyarrow`")
def test_dataframe_to_arrow_with_multiindex(module_under_test):
diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py
index c4c604ed0..f44201ab8 100644
--- a/tests/unit/test_client.py
+++ b/tests/unit/test_client.py
@@ -48,7 +48,7 @@
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
InMemorySpanExporter,
)
-except (ImportError, AttributeError):
+except (ImportError, AttributeError): # pragma: NO COVER
opentelemetry = None
try:
import pyarrow
@@ -62,9 +62,9 @@
from google.cloud.bigquery.dataset import DatasetReference
try:
- from google.cloud import bigquery_storage_v1
+ from google.cloud import bigquery_storage
except (ImportError, AttributeError): # pragma: NO COVER
- bigquery_storage_v1 = None
+ bigquery_storage = None
from test_utils.imports import maybe_fail_import
from tests.unit.helpers import make_connection
@@ -794,17 +794,17 @@ def test_get_dataset(self):
self.assertEqual(dataset.dataset_id, self.DS_ID)
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_create_bqstorage_client(self):
- mock_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ mock_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
mock_client_instance = object()
mock_client.return_value = mock_client_instance
creds = _make_credentials()
client = self._make_one(project=self.PROJECT, credentials=creds)
with mock.patch(
- "google.cloud.bigquery_storage_v1.BigQueryReadClient", mock_client
+ "google.cloud.bigquery_storage.BigQueryReadClient", mock_client
):
bqstorage_client = client._create_bqstorage_client()
@@ -817,8 +817,8 @@ def test_create_bqstorage_client_missing_dependency(self):
def fail_bqstorage_import(name, globals, locals, fromlist, level):
# NOTE: *very* simplified, assuming a straightforward absolute import
- return "bigquery_storage_v1" in name or (
- fromlist is not None and "bigquery_storage_v1" in fromlist
+ return "bigquery_storage" in name or (
+ fromlist is not None and "bigquery_storage" in fromlist
)
no_bqstorage = maybe_fail_import(predicate=fail_bqstorage_import)
@@ -2499,7 +2499,7 @@ def test_update_routine(self):
RoutineArgument(
name="x",
data_type=bigquery_v2.types.StandardSqlDataType(
- type_kind=bigquery_v2.enums.StandardSqlDataType.TypeKind.INT64
+ type_kind=bigquery_v2.types.StandardSqlDataType.TypeKind.INT64
),
)
]
@@ -8032,49 +8032,35 @@ def test_load_table_from_dataframe_struct_fields(self):
"google.cloud.bigquery.client.Client.load_table_from_file", autospec=True
)
- if six.PY2:
- with pytest.raises(ValueError) as exc_info, load_patch:
- client.load_table_from_dataframe(
- dataframe,
- self.TABLE_REF,
- job_config=job_config,
- location=self.LOCATION,
- )
-
- err_msg = str(exc_info.value)
- assert "struct" in err_msg
- assert "not support" in err_msg
-
- else:
- get_table_patch = mock.patch(
- "google.cloud.bigquery.client.Client.get_table",
- autospec=True,
- side_effect=google.api_core.exceptions.NotFound("Table not found"),
- )
- with load_patch as load_table_from_file, get_table_patch:
- client.load_table_from_dataframe(
- dataframe,
- self.TABLE_REF,
- job_config=job_config,
- location=self.LOCATION,
- )
-
- load_table_from_file.assert_called_once_with(
- client,
- mock.ANY,
+ get_table_patch = mock.patch(
+ "google.cloud.bigquery.client.Client.get_table",
+ autospec=True,
+ side_effect=google.api_core.exceptions.NotFound("Table not found"),
+ )
+ with load_patch as load_table_from_file, get_table_patch:
+ client.load_table_from_dataframe(
+ dataframe,
self.TABLE_REF,
- num_retries=_DEFAULT_NUM_RETRIES,
- rewind=True,
- job_id=mock.ANY,
- job_id_prefix=None,
+ job_config=job_config,
location=self.LOCATION,
- project=None,
- job_config=mock.ANY,
)
- sent_config = load_table_from_file.mock_calls[0][2]["job_config"]
- assert sent_config.source_format == job.SourceFormat.PARQUET
- assert sent_config.schema == schema
+ load_table_from_file.assert_called_once_with(
+ client,
+ mock.ANY,
+ self.TABLE_REF,
+ num_retries=_DEFAULT_NUM_RETRIES,
+ rewind=True,
+ job_id=mock.ANY,
+ job_id_prefix=None,
+ location=self.LOCATION,
+ project=None,
+ job_config=mock.ANY,
+ )
+
+ sent_config = load_table_from_file.mock_calls[0][2]["job_config"]
+ assert sent_config.source_format == job.SourceFormat.PARQUET
+ assert sent_config.schema == schema
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
@@ -8671,14 +8657,9 @@ def test_schema_from_json_with_file_path(self):
client = self._make_client()
mock_file_path = "/mocked/file.json"
- if six.PY2:
- open_patch = mock.patch(
- "__builtin__.open", mock.mock_open(read_data=file_content)
- )
- else:
- open_patch = mock.patch(
- "builtins.open", new=mock.mock_open(read_data=file_content)
- )
+ open_patch = mock.patch(
+ "builtins.open", new=mock.mock_open(read_data=file_content)
+ )
with open_patch as _mock_file:
actual = client.schema_from_json(mock_file_path)
@@ -8720,12 +8701,7 @@ def test_schema_from_json_with_file_object(self):
]
client = self._make_client()
-
- if six.PY2:
- fake_file = io.BytesIO(file_content)
- else:
- fake_file = io.StringIO(file_content)
-
+ fake_file = io.StringIO(file_content)
actual = client.schema_from_json(fake_file)
assert expected == actual
@@ -8762,11 +8738,7 @@ def test_schema_to_json_with_file_path(self):
client = self._make_client()
mock_file_path = "/mocked/file.json"
-
- if six.PY2:
- open_patch = mock.patch("__builtin__.open", mock.mock_open())
- else:
- open_patch = mock.patch("builtins.open", mock.mock_open())
+ open_patch = mock.patch("builtins.open", mock.mock_open())
with open_patch as mock_file, mock.patch("json.dump") as mock_dump:
client.schema_to_json(schema_list, mock_file_path)
@@ -8808,10 +8780,7 @@ def test_schema_to_json_with_file_object(self):
SchemaField("sales", "FLOAT", "NULLABLE", "total sales"),
]
- if six.PY2:
- fake_file = io.BytesIO()
- else:
- fake_file = io.StringIO()
+ fake_file = io.StringIO()
client = self._make_client()
diff --git a/tests/unit/test_dbapi_connection.py b/tests/unit/test_dbapi_connection.py
index 0f1be45ee..30fb1292e 100644
--- a/tests/unit/test_dbapi_connection.py
+++ b/tests/unit/test_dbapi_connection.py
@@ -19,9 +19,9 @@
import six
try:
- from google.cloud import bigquery_storage_v1
+ from google.cloud import bigquery_storage
except ImportError: # pragma: NO COVER
- bigquery_storage_v1 = None
+ bigquery_storage = None
class TestConnection(unittest.TestCase):
@@ -41,29 +41,26 @@ def _mock_client(self):
return mock_client
def _mock_bqstorage_client(self):
- if bigquery_storage_v1 is None:
- return None
- mock_client = mock.create_autospec(
- bigquery_storage_v1.client.BigQueryReadClient
- )
- mock_client.transport = mock.Mock(spec=["channel"])
- mock_client.transport.channel = mock.Mock(spec=["close"])
+ # Assumption: bigquery_storage exists. It's the test's responisbility to
+ # not use this helper or skip itself if bqstroage is not installed.
+ mock_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ mock_client._transport = mock.Mock(spec=["channel"])
+ mock_client._transport.grpc_channel = mock.Mock(spec=["close"])
return mock_client
def test_ctor_wo_bqstorage_client(self):
from google.cloud.bigquery.dbapi import Connection
mock_client = self._mock_client()
- mock_bqstorage_client = self._mock_bqstorage_client()
- mock_client._create_bqstorage_client.return_value = mock_bqstorage_client
+ mock_client._create_bqstorage_client.return_value = None
connection = self._make_one(client=mock_client)
self.assertIsInstance(connection, Connection)
self.assertIs(connection._client, mock_client)
- self.assertIs(connection._bqstorage_client, mock_bqstorage_client)
+ self.assertIs(connection._bqstorage_client, None)
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_ctor_w_bqstorage_client(self):
from google.cloud.bigquery.dbapi import Connection
@@ -87,6 +84,9 @@ def test_connect_wo_client(self, mock_client):
self.assertIsNotNone(connection._client)
self.assertIsNotNone(connection._bqstorage_client)
+ @unittest.skipIf(
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
+ )
def test_connect_w_client(self):
from google.cloud.bigquery.dbapi import connect
from google.cloud.bigquery.dbapi import Connection
@@ -101,7 +101,7 @@ def test_connect_w_client(self):
self.assertIs(connection._bqstorage_client, mock_bqstorage_client)
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_connect_w_both_clients(self):
from google.cloud.bigquery.dbapi import connect
@@ -130,7 +130,7 @@ def test_raises_error_if_closed(self):
getattr(connection, method)()
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_close_closes_all_created_bigquery_clients(self):
client = self._mock_client()
@@ -150,10 +150,10 @@ def test_close_closes_all_created_bigquery_clients(self):
connection.close()
self.assertTrue(client.close.called)
- self.assertTrue(bqstorage_client.transport.channel.close.called)
+ self.assertTrue(bqstorage_client._transport.grpc_channel.close.called)
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_close_does_not_close_bigquery_clients_passed_to_it(self):
client = self._mock_client()
@@ -163,7 +163,7 @@ def test_close_does_not_close_bigquery_clients_passed_to_it(self):
connection.close()
self.assertFalse(client.close.called)
- self.assertFalse(bqstorage_client.transport.channel.called)
+ self.assertFalse(bqstorage_client._transport.grpc_channel.close.called)
def test_close_closes_all_created_cursors(self):
connection = self._make_one(client=self._mock_client())
diff --git a/tests/unit/test_dbapi_cursor.py b/tests/unit/test_dbapi_cursor.py
index bd1d9dc0a..9a1a6b1e8 100644
--- a/tests/unit/test_dbapi_cursor.py
+++ b/tests/unit/test_dbapi_cursor.py
@@ -14,7 +14,6 @@
import operator as op
import unittest
-import warnings
import mock
import six
@@ -27,11 +26,9 @@
from google.api_core import exceptions
try:
- from google.cloud import bigquery_storage_v1
- from google.cloud import bigquery_storage_v1beta1
+ from google.cloud import bigquery_storage
except ImportError: # pragma: NO COVER
- bigquery_storage_v1 = None
- bigquery_storage_v1beta1 = None
+ bigquery_storage = None
from tests.unit.helpers import _to_pyarrow
@@ -78,32 +75,17 @@ def _mock_client(
return mock_client
- def _mock_bqstorage_client(self, rows=None, stream_count=0, v1beta1=False):
- from google.cloud.bigquery_storage_v1 import client
- from google.cloud.bigquery_storage_v1 import types
- from google.cloud.bigquery_storage_v1beta1 import types as types_v1beta1
-
+ def _mock_bqstorage_client(self, rows=None, stream_count=0):
if rows is None:
rows = []
- if v1beta1:
- mock_client = mock.create_autospec(
- bigquery_storage_v1beta1.BigQueryStorageClient
- )
- mock_read_session = mock.MagicMock(
- streams=[
- types_v1beta1.Stream(name="streams/stream_{}".format(i))
- for i in range(stream_count)
- ]
- )
- else:
- mock_client = mock.create_autospec(client.BigQueryReadClient)
- mock_read_session = mock.MagicMock(
- streams=[
- types.ReadStream(name="streams/stream_{}".format(i))
- for i in range(stream_count)
- ]
- )
+ mock_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ mock_read_session = mock.MagicMock(
+ streams=[
+ bigquery_storage.types.ReadStream(name="streams/stream_{}".format(i))
+ for i in range(stream_count)
+ ]
+ )
mock_client.create_read_session.return_value = mock_read_session
@@ -291,7 +273,7 @@ def test_fetchall_w_row(self):
self.assertEqual(rows[0], (1,))
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_fetchall_w_bqstorage_client_fetch_success(self):
@@ -345,71 +327,7 @@ def test_fetchall_w_bqstorage_client_fetch_success(self):
self.assertEqual(sorted_row_data, expected_row_data)
@unittest.skipIf(
- bigquery_storage_v1beta1 is None, "Requires `google-cloud-bigquery-storage`"
- )
- @unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
- def test_fetchall_w_bqstorage_client_v1beta1_fetch_success(self):
- from google.cloud.bigquery import dbapi
- from google.cloud.bigquery import table
-
- # use unordered data to also test any non-determenistic key order in dicts
- row_data = [
- table.Row([1.4, 1.1, 1.3, 1.2], {"bar": 3, "baz": 2, "foo": 1, "quux": 0}),
- table.Row([2.4, 2.1, 2.3, 2.2], {"bar": 3, "baz": 2, "foo": 1, "quux": 0}),
- ]
- bqstorage_streamed_rows = [
- {
- "bar": _to_pyarrow(1.2),
- "foo": _to_pyarrow(1.1),
- "quux": _to_pyarrow(1.4),
- "baz": _to_pyarrow(1.3),
- },
- {
- "bar": _to_pyarrow(2.2),
- "foo": _to_pyarrow(2.1),
- "quux": _to_pyarrow(2.4),
- "baz": _to_pyarrow(2.3),
- },
- ]
-
- mock_client = self._mock_client(rows=row_data)
- mock_bqstorage_client = self._mock_bqstorage_client(
- stream_count=1, rows=bqstorage_streamed_rows, v1beta1=True
- )
-
- connection = dbapi.connect(
- client=mock_client, bqstorage_client=mock_bqstorage_client,
- )
- cursor = connection.cursor()
- cursor.execute("SELECT foo, bar FROM some_table")
-
- with warnings.catch_warnings(record=True) as warned:
- rows = cursor.fetchall()
-
- # a deprecation warning should have been emitted
- expected_warnings = [
- warning
- for warning in warned
- if issubclass(warning.category, DeprecationWarning)
- and "v1beta1" in str(warning)
- ]
- self.assertEqual(len(expected_warnings), 1, "Deprecation warning not raised.")
-
- # the default client was not used
- mock_client.list_rows.assert_not_called()
-
- # check the data returned
- field_value = op.itemgetter(1)
- sorted_row_data = [sorted(row.items(), key=field_value) for row in rows]
- expected_row_data = [
- [("foo", 1.1), ("bar", 1.2), ("baz", 1.3), ("quux", 1.4)],
- [("foo", 2.1), ("bar", 2.2), ("baz", 2.3), ("quux", 2.4)],
- ]
-
- self.assertEqual(sorted_row_data, expected_row_data)
-
- @unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_fetchall_w_bqstorage_client_fetch_no_rows(self):
from google.cloud.bigquery import dbapi
@@ -432,7 +350,7 @@ def test_fetchall_w_bqstorage_client_fetch_no_rows(self):
self.assertEqual(rows, [])
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_fetchall_w_bqstorage_client_fetch_error_no_fallback(self):
from google.cloud.bigquery import dbapi
diff --git a/tests/unit/test_job.py b/tests/unit/test_job.py
index fb6a46bd6..fb042e18c 100644
--- a/tests/unit/test_job.py
+++ b/tests/unit/test_job.py
@@ -35,9 +35,9 @@
except ImportError: # pragma: NO COVER
pyarrow = None
try:
- from google.cloud import bigquery_storage_v1
+ from google.cloud import bigquery_storage
except (ImportError, AttributeError): # pragma: NO COVER
- bigquery_storage_v1 = None
+ bigquery_storage = None
try:
from tqdm import tqdm
except (ImportError, AttributeError): # pragma: NO COVER
@@ -5667,7 +5667,7 @@ def test_to_dataframe_ddl_query(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_dataframe_bqstorage(self):
query_resource = {
@@ -5685,8 +5685,8 @@ def test_to_dataframe_bqstorage(self):
client = _make_client(self.PROJECT, connection=connection)
resource = self._make_resource(ended=True)
job = self._get_target_class().from_api_repr(resource, client)
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- session = bigquery_storage_v1.types.ReadSession()
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ session = bigquery_storage.types.ReadSession()
session.avro_schema.schema = json.dumps(
{
"type": "record",
@@ -5704,9 +5704,9 @@ def test_to_dataframe_bqstorage(self):
destination_table = "projects/{projectId}/datasets/{datasetId}/tables/{tableId}".format(
**resource["configuration"]["query"]["destinationTable"]
)
- expected_session = bigquery_storage_v1.types.ReadSession(
+ expected_session = bigquery_storage.types.ReadSession(
table=destination_table,
- data_format=bigquery_storage_v1.enums.DataFormat.ARROW,
+ data_format=bigquery_storage.types.DataFormat.ARROW,
)
bqstorage_client.create_read_session.assert_called_once_with(
parent="projects/{}".format(self.PROJECT),
@@ -6259,7 +6259,7 @@ def test__contains_order_by(query, expected):
@pytest.mark.skipif(pandas is None, reason="Requires `pandas`")
@pytest.mark.skipif(
- bigquery_storage_v1 is None, reason="Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, reason="Requires `google-cloud-bigquery-storage`"
)
@pytest.mark.parametrize(
"query",
@@ -6295,8 +6295,8 @@ def test_to_dataframe_bqstorage_preserve_order(query):
connection = _make_connection(get_query_results_resource, job_resource)
client = _make_client(connection=connection)
job = target_class.from_api_repr(job_resource, client)
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- session = bigquery_storage_v1.types.ReadSession()
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ session = bigquery_storage.types.ReadSession()
session.avro_schema.schema = json.dumps(
{
"type": "record",
@@ -6314,8 +6314,8 @@ def test_to_dataframe_bqstorage_preserve_order(query):
destination_table = "projects/{projectId}/datasets/{datasetId}/tables/{tableId}".format(
**job_resource["configuration"]["query"]["destinationTable"]
)
- expected_session = bigquery_storage_v1.types.ReadSession(
- table=destination_table, data_format=bigquery_storage_v1.enums.DataFormat.ARROW,
+ expected_session = bigquery_storage.types.ReadSession(
+ table=destination_table, data_format=bigquery_storage.types.DataFormat.ARROW,
)
bqstorage_client.create_read_session.assert_called_once_with(
parent="projects/test-project",
diff --git a/tests/unit/test_magics.py b/tests/unit/test_magics.py
index c4527c837..20be6b755 100644
--- a/tests/unit/test_magics.py
+++ b/tests/unit/test_magics.py
@@ -41,7 +41,7 @@
io = pytest.importorskip("IPython.utils.io")
tools = pytest.importorskip("IPython.testing.tools")
interactiveshell = pytest.importorskip("IPython.terminal.interactiveshell")
-bigquery_storage_v1 = pytest.importorskip("google.cloud.bigquery_storage_v1")
+bigquery_storage = pytest.importorskip("google.cloud.bigquery_storage")
@pytest.fixture(scope="session")
@@ -83,8 +83,8 @@ def missing_bq_storage():
def fail_if(name, globals, locals, fromlist, level):
# NOTE: *very* simplified, assuming a straightforward absolute import
- return "bigquery_storage_v1" in name or (
- fromlist is not None and "bigquery_storage_v1" in fromlist
+ return "bigquery_storage" in name or (
+ fromlist is not None and "bigquery_storage" in fromlist
)
return maybe_fail_import(predicate=fail_if)
@@ -314,14 +314,14 @@ def test__make_bqstorage_client_false():
@pytest.mark.skipif(
- bigquery_storage_v1 is None, reason="Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, reason="Requires `google-cloud-bigquery-storage`"
)
def test__make_bqstorage_client_true():
credentials_mock = mock.create_autospec(
google.auth.credentials.Credentials, instance=True
)
got = magics._make_bqstorage_client(True, credentials_mock)
- assert isinstance(got, bigquery_storage_v1.BigQueryReadClient)
+ assert isinstance(got, bigquery_storage.BigQueryReadClient)
def test__make_bqstorage_client_true_raises_import_error(missing_bq_storage):
@@ -338,7 +338,7 @@ def test__make_bqstorage_client_true_raises_import_error(missing_bq_storage):
@pytest.mark.skipif(
- bigquery_storage_v1 is None, reason="Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, reason="Requires `google-cloud-bigquery-storage`"
)
@pytest.mark.skipif(pandas is None, reason="Requires `pandas`")
def test__make_bqstorage_client_true_missing_gapic(missing_grpcio_lib):
@@ -396,7 +396,7 @@ def test_extension_load():
@pytest.mark.usefixtures("ipython_interactive")
@pytest.mark.skipif(pandas is None, reason="Requires `pandas`")
@pytest.mark.skipif(
- bigquery_storage_v1 is None, reason="Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, reason="Requires `google-cloud-bigquery-storage`"
)
def test_bigquery_magic_without_optional_arguments(monkeypatch):
ip = IPython.get_ipython()
@@ -410,14 +410,14 @@ def test_bigquery_magic_without_optional_arguments(monkeypatch):
monkeypatch.setattr(magics.context, "_credentials", mock_credentials)
# Mock out the BigQuery Storage API.
- bqstorage_mock = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ bqstorage_mock = mock.create_autospec(bigquery_storage.BigQueryReadClient)
bqstorage_instance_mock = mock.create_autospec(
- bigquery_storage_v1.BigQueryReadClient, instance=True
+ bigquery_storage.BigQueryReadClient, instance=True
)
- bqstorage_instance_mock.transport = mock.Mock()
+ bqstorage_instance_mock._transport = mock.Mock()
bqstorage_mock.return_value = bqstorage_instance_mock
bqstorage_client_patch = mock.patch(
- "google.cloud.bigquery_storage_v1.BigQueryReadClient", bqstorage_mock
+ "google.cloud.bigquery_storage.BigQueryReadClient", bqstorage_mock
)
sql = "SELECT 17 AS num"
@@ -559,7 +559,7 @@ def test_bigquery_magic_clears_display_in_verbose_mode():
@pytest.mark.usefixtures("ipython_interactive")
@pytest.mark.skipif(
- bigquery_storage_v1 is None, reason="Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, reason="Requires `google-cloud-bigquery-storage`"
)
def test_bigquery_magic_with_bqstorage_from_argument(monkeypatch):
ip = IPython.get_ipython()
@@ -573,14 +573,14 @@ def test_bigquery_magic_with_bqstorage_from_argument(monkeypatch):
monkeypatch.setattr(magics.context, "_credentials", mock_credentials)
# Mock out the BigQuery Storage API.
- bqstorage_mock = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ bqstorage_mock = mock.create_autospec(bigquery_storage.BigQueryReadClient)
bqstorage_instance_mock = mock.create_autospec(
- bigquery_storage_v1.BigQueryReadClient, instance=True
+ bigquery_storage.BigQueryReadClient, instance=True
)
- bqstorage_instance_mock.transport = mock.Mock()
+ bqstorage_instance_mock._transport = mock.Mock()
bqstorage_mock.return_value = bqstorage_instance_mock
bqstorage_client_patch = mock.patch(
- "google.cloud.bigquery_storage_v1.BigQueryReadClient", bqstorage_mock
+ "google.cloud.bigquery_storage.BigQueryReadClient", bqstorage_mock
)
sql = "SELECT 17 AS num"
@@ -623,7 +623,7 @@ def warning_match(warning):
@pytest.mark.usefixtures("ipython_interactive")
@pytest.mark.skipif(
- bigquery_storage_v1 is None, reason="Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, reason="Requires `google-cloud-bigquery-storage`"
)
def test_bigquery_magic_with_rest_client_requested(monkeypatch):
ip = IPython.get_ipython()
@@ -637,9 +637,9 @@ def test_bigquery_magic_with_rest_client_requested(monkeypatch):
monkeypatch.setattr(magics.context, "_credentials", mock_credentials)
# Mock out the BigQuery Storage API.
- bqstorage_mock = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ bqstorage_mock = mock.create_autospec(bigquery_storage.BigQueryReadClient)
bqstorage_client_patch = mock.patch(
- "google.cloud.bigquery_storage_v1.BigQueryReadClient", bqstorage_mock
+ "google.cloud.bigquery_storage.BigQueryReadClient", bqstorage_mock
)
sql = "SELECT 17 AS num"
@@ -841,7 +841,7 @@ def test_bigquery_magic_w_table_id_and_destination_var(ipython_ns_cleanup):
@pytest.mark.usefixtures("ipython_interactive")
@pytest.mark.skipif(
- bigquery_storage_v1 is None, reason="Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, reason="Requires `google-cloud-bigquery-storage`"
)
@pytest.mark.skipif(pandas is None, reason="Requires `pandas`")
def test_bigquery_magic_w_table_id_and_bqstorage_client():
@@ -864,14 +864,14 @@ def test_bigquery_magic_w_table_id_and_bqstorage_client():
"google.cloud.bigquery.magics.magics.bigquery.Client", autospec=True
)
- bqstorage_mock = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ bqstorage_mock = mock.create_autospec(bigquery_storage.BigQueryReadClient)
bqstorage_instance_mock = mock.create_autospec(
- bigquery_storage_v1.BigQueryReadClient, instance=True
+ bigquery_storage.BigQueryReadClient, instance=True
)
- bqstorage_instance_mock.transport = mock.Mock()
+ bqstorage_instance_mock._transport = mock.Mock()
bqstorage_mock.return_value = bqstorage_instance_mock
bqstorage_client_patch = mock.patch(
- "google.cloud.bigquery_storage_v1.BigQueryReadClient", bqstorage_mock
+ "google.cloud.bigquery_storage.BigQueryReadClient", bqstorage_mock
)
table_id = "bigquery-public-data.samples.shakespeare"
diff --git a/tests/unit/test_opentelemetry_tracing.py b/tests/unit/test_opentelemetry_tracing.py
index 1c35b0a82..09afa7531 100644
--- a/tests/unit/test_opentelemetry_tracing.py
+++ b/tests/unit/test_opentelemetry_tracing.py
@@ -25,7 +25,7 @@
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
InMemorySpanExporter,
)
-except ImportError:
+except ImportError: # pragma: NO COVER
opentelemetry = None
import pytest
from six.moves import reload_module
diff --git a/tests/unit/test_schema.py b/tests/unit/test_schema.py
index 9f7ee7bb3..71bf6b5ae 100644
--- a/tests/unit/test_schema.py
+++ b/tests/unit/test_schema.py
@@ -206,15 +206,15 @@ def test_to_standard_sql_simple_type(self):
sql_type = self._get_standard_sql_data_type_class()
examples = (
# a few legacy types
- ("INTEGER", sql_type.INT64),
- ("FLOAT", sql_type.FLOAT64),
- ("BOOLEAN", sql_type.BOOL),
- ("DATETIME", sql_type.DATETIME),
+ ("INTEGER", sql_type.TypeKind.INT64),
+ ("FLOAT", sql_type.TypeKind.FLOAT64),
+ ("BOOLEAN", sql_type.TypeKind.BOOL),
+ ("DATETIME", sql_type.TypeKind.DATETIME),
# a few standard types
- ("INT64", sql_type.INT64),
- ("FLOAT64", sql_type.FLOAT64),
- ("BOOL", sql_type.BOOL),
- ("GEOGRAPHY", sql_type.GEOGRAPHY),
+ ("INT64", sql_type.TypeKind.INT64),
+ ("FLOAT64", sql_type.TypeKind.FLOAT64),
+ ("BOOL", sql_type.TypeKind.BOOL),
+ ("GEOGRAPHY", sql_type.TypeKind.GEOGRAPHY),
)
for legacy_type, standard_type in examples:
field = self._make_one("some_field", legacy_type)
@@ -258,26 +258,26 @@ def test_to_standard_sql_struct_type(self):
# level 2 fields
sub_sub_field_date = types.StandardSqlField(
- name="date_field", type=sql_type(type_kind=sql_type.DATE)
+ name="date_field", type=sql_type(type_kind=sql_type.TypeKind.DATE)
)
sub_sub_field_time = types.StandardSqlField(
- name="time_field", type=sql_type(type_kind=sql_type.TIME)
+ name="time_field", type=sql_type(type_kind=sql_type.TypeKind.TIME)
)
# level 1 fields
sub_field_struct = types.StandardSqlField(
- name="last_used", type=sql_type(type_kind=sql_type.STRUCT)
+ name="last_used", type=sql_type(type_kind=sql_type.TypeKind.STRUCT)
)
sub_field_struct.type.struct_type.fields.extend(
[sub_sub_field_date, sub_sub_field_time]
)
sub_field_bytes = types.StandardSqlField(
- name="image_content", type=sql_type(type_kind=sql_type.BYTES)
+ name="image_content", type=sql_type(type_kind=sql_type.TypeKind.BYTES)
)
# level 0 (top level)
expected_result = types.StandardSqlField(
- name="image_usage", type=sql_type(type_kind=sql_type.STRUCT)
+ name="image_usage", type=sql_type(type_kind=sql_type.TypeKind.STRUCT)
)
expected_result.type.struct_type.fields.extend(
[sub_field_bytes, sub_field_struct]
@@ -304,8 +304,8 @@ def test_to_standard_sql_array_type_simple(self):
sql_type = self._get_standard_sql_data_type_class()
# construct expected result object
- expected_sql_type = sql_type(type_kind=sql_type.ARRAY)
- expected_sql_type.array_element_type.type_kind = sql_type.INT64
+ expected_sql_type = sql_type(type_kind=sql_type.TypeKind.ARRAY)
+ expected_sql_type.array_element_type.type_kind = sql_type.TypeKind.INT64
expected_result = types.StandardSqlField(
name="valid_numbers", type=expected_sql_type
)
@@ -323,19 +323,19 @@ def test_to_standard_sql_array_type_struct(self):
# define person STRUCT
name_field = types.StandardSqlField(
- name="name", type=sql_type(type_kind=sql_type.STRING)
+ name="name", type=sql_type(type_kind=sql_type.TypeKind.STRING)
)
age_field = types.StandardSqlField(
- name="age", type=sql_type(type_kind=sql_type.INT64)
+ name="age", type=sql_type(type_kind=sql_type.TypeKind.INT64)
)
person_struct = types.StandardSqlField(
- name="person_info", type=sql_type(type_kind=sql_type.STRUCT)
+ name="person_info", type=sql_type(type_kind=sql_type.TypeKind.STRUCT)
)
person_struct.type.struct_type.fields.extend([name_field, age_field])
# define expected result - an ARRAY of person structs
expected_sql_type = sql_type(
- type_kind=sql_type.ARRAY, array_element_type=person_struct.type
+ type_kind=sql_type.TypeKind.ARRAY, array_element_type=person_struct.type
)
expected_result = types.StandardSqlField(
name="known_people", type=expected_sql_type
@@ -358,7 +358,9 @@ def test_to_standard_sql_unknown_type(self):
standard_field = field.to_standard_sql()
self.assertEqual(standard_field.name, "weird_field")
- self.assertEqual(standard_field.type.type_kind, sql_type.TYPE_KIND_UNSPECIFIED)
+ self.assertEqual(
+ standard_field.type.type_kind, sql_type.TypeKind.TYPE_KIND_UNSPECIFIED
+ )
def test___eq___wrong_type(self):
field = self._make_one("test", "STRING")
diff --git a/tests/unit/test_table.py b/tests/unit/test_table.py
index 10bedfee1..12169658e 100644
--- a/tests/unit/test_table.py
+++ b/tests/unit/test_table.py
@@ -13,7 +13,6 @@
# limitations under the License.
import datetime as dt
-import itertools
import logging
import time
import unittest
@@ -26,19 +25,13 @@
import google.api_core.exceptions
try:
- from google.cloud import bigquery_storage_v1
- from google.cloud import bigquery_storage_v1beta1
- from google.cloud.bigquery_storage_v1.gapic.transports import (
- big_query_read_grpc_transport,
- )
- from google.cloud.bigquery_storage_v1beta1.gapic.transports import (
- big_query_storage_grpc_transport as big_query_storage_grpc_transport_v1beta1,
+ from google.cloud import bigquery_storage
+ from google.cloud.bigquery_storage_v1.services.big_query_read.transports import (
+ grpc as big_query_read_grpc_transport,
)
except ImportError: # pragma: NO COVER
- bigquery_storage_v1 = None
- bigquery_storage_v1beta1 = None
+ bigquery_storage = None
big_query_read_grpc_transport = None
- big_query_storage_grpc_transport_v1beta1 = None
try:
import pandas
@@ -1846,7 +1839,7 @@ def test_to_arrow_w_empty_table(self):
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_arrow_max_results_w_create_bqstorage_warning(self):
from google.cloud.bigquery.schema import SchemaField
@@ -1886,15 +1879,15 @@ def test_to_arrow_max_results_w_create_bqstorage_warning(self):
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_arrow_w_bqstorage(self):
from google.cloud.bigquery import schema
from google.cloud.bigquery import table as mut
from google.cloud.bigquery_storage_v1 import reader
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- bqstorage_client.transport = mock.create_autospec(
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ bqstorage_client._transport = mock.create_autospec(
big_query_read_grpc_transport.BigQueryReadGrpcTransport
)
streams = [
@@ -1902,7 +1895,7 @@ def test_to_arrow_w_bqstorage(self):
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/1234"},
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/5678"},
]
- session = bigquery_storage_v1.types.ReadSession(streams=streams)
+ session = bigquery_storage.types.ReadSession(streams=streams)
arrow_schema = pyarrow.schema(
[
pyarrow.field("colA", pyarrow.int64()),
@@ -1963,23 +1956,23 @@ def test_to_arrow_w_bqstorage(self):
self.assertEqual(actual_tbl.num_rows, total_rows)
# Don't close the client if it was passed in.
- bqstorage_client.transport.channel.close.assert_not_called()
+ bqstorage_client._transport.grpc_channel.close.assert_not_called()
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_arrow_w_bqstorage_creates_client(self):
from google.cloud.bigquery import schema
from google.cloud.bigquery import table as mut
mock_client = _mock_client()
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- bqstorage_client.transport = mock.create_autospec(
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ bqstorage_client._transport = mock.create_autospec(
big_query_read_grpc_transport.BigQueryReadGrpcTransport
)
mock_client._create_bqstorage_client.return_value = bqstorage_client
- session = bigquery_storage_v1.types.ReadSession()
+ session = bigquery_storage.types.ReadSession()
bqstorage_client.create_read_session.return_value = session
row_iterator = mut.RowIterator(
mock_client,
@@ -1994,7 +1987,7 @@ def test_to_arrow_w_bqstorage_creates_client(self):
)
row_iterator.to_arrow(create_bqstorage_client=True)
mock_client._create_bqstorage_client.assert_called_once()
- bqstorage_client.transport.channel.close.assert_called_once()
+ bqstorage_client._transport.grpc_channel.close.assert_called_once()
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_to_arrow_create_bqstorage_client_wo_bqstorage(self):
@@ -2025,14 +2018,14 @@ def test_to_arrow_create_bqstorage_client_wo_bqstorage(self):
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_arrow_w_bqstorage_no_streams(self):
from google.cloud.bigquery import schema
from google.cloud.bigquery import table as mut
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- session = bigquery_storage_v1.types.ReadSession()
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ session = bigquery_storage.types.ReadSession()
arrow_schema = pyarrow.schema(
[
pyarrow.field("colA", pyarrow.string()),
@@ -2157,7 +2150,7 @@ def test_to_dataframe_iterable(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_to_dataframe_iterable_w_bqstorage(self):
@@ -2173,8 +2166,8 @@ def test_to_dataframe_iterable_w_bqstorage(self):
]
arrow_schema = pyarrow.schema(arrow_fields)
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- bqstorage_client.transport = mock.create_autospec(
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ bqstorage_client._transport = mock.create_autospec(
big_query_read_grpc_transport.BigQueryReadGrpcTransport
)
streams = [
@@ -2182,7 +2175,7 @@ def test_to_dataframe_iterable_w_bqstorage(self):
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/1234"},
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/5678"},
]
- session = bigquery_storage_v1.types.ReadSession(
+ session = bigquery_storage.types.ReadSession(
streams=streams,
arrow_schema={"serialized_schema": arrow_schema.serialize().to_pybytes()},
)
@@ -2225,7 +2218,7 @@ def test_to_dataframe_iterable_w_bqstorage(self):
self.assertEqual(len(got), total_pages)
# Don't close the client if it was passed in.
- bqstorage_client.transport.channel.close.assert_not_called()
+ bqstorage_client._transport.grpc_channel.close.assert_not_called()
@mock.patch("google.cloud.bigquery.table.pandas", new=None)
def test_to_dataframe_iterable_error_if_pandas_is_none(self):
@@ -2790,19 +2783,19 @@ def test_to_dataframe_max_results_w_create_bqstorage_warning(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_dataframe_w_bqstorage_creates_client(self):
from google.cloud.bigquery import schema
from google.cloud.bigquery import table as mut
mock_client = _mock_client()
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- bqstorage_client.transport = mock.create_autospec(
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ bqstorage_client._transport = mock.create_autospec(
big_query_read_grpc_transport.BigQueryReadGrpcTransport
)
mock_client._create_bqstorage_client.return_value = bqstorage_client
- session = bigquery_storage_v1.types.ReadSession()
+ session = bigquery_storage.types.ReadSession()
bqstorage_client.create_read_session.return_value = session
row_iterator = mut.RowIterator(
mock_client,
@@ -2817,18 +2810,18 @@ def test_to_dataframe_w_bqstorage_creates_client(self):
)
row_iterator.to_dataframe(create_bqstorage_client=True)
mock_client._create_bqstorage_client.assert_called_once()
- bqstorage_client.transport.channel.close.assert_called_once()
+ bqstorage_client._transport.grpc_channel.close.assert_called_once()
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_dataframe_w_bqstorage_no_streams(self):
from google.cloud.bigquery import schema
from google.cloud.bigquery import table as mut
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- session = bigquery_storage_v1.types.ReadSession()
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ session = bigquery_storage.types.ReadSession()
bqstorage_client.create_read_session.return_value = session
row_iterator = mut.RowIterator(
@@ -2848,55 +2841,16 @@ def test_to_dataframe_w_bqstorage_no_streams(self):
self.assertEqual(list(got), column_names)
self.assertTrue(got.empty)
- @unittest.skipIf(pandas is None, "Requires `pandas`")
- @unittest.skipIf(
- bigquery_storage_v1beta1 is None, "Requires `google-cloud-bigquery-storage`"
- )
- def test_to_dataframe_w_bqstorage_v1beta1_no_streams(self):
- from google.cloud.bigquery import schema
- from google.cloud.bigquery import table as mut
-
- bqstorage_client = mock.create_autospec(
- bigquery_storage_v1beta1.BigQueryStorageClient
- )
- session = bigquery_storage_v1beta1.types.ReadSession()
- bqstorage_client.create_read_session.return_value = session
-
- row_iterator = mut.RowIterator(
- _mock_client(),
- api_request=None,
- path=None,
- schema=[
- schema.SchemaField("colA", "INTEGER"),
- schema.SchemaField("colC", "FLOAT"),
- schema.SchemaField("colB", "STRING"),
- ],
- table=mut.TableReference.from_string("proj.dset.tbl"),
- )
-
- with warnings.catch_warnings(record=True) as warned:
- got = row_iterator.to_dataframe(bqstorage_client)
-
- column_names = ["colA", "colC", "colB"]
- self.assertEqual(list(got), column_names)
- self.assertTrue(got.empty)
-
- self.assertEqual(len(warned), 1)
- warning = warned[0]
- self.assertTrue(
- "Support for BigQuery Storage v1beta1 clients is deprecated" in str(warning)
- )
-
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_to_dataframe_w_bqstorage_logs_session(self):
from google.cloud.bigquery.table import Table
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- session = bigquery_storage_v1.types.ReadSession()
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ session = bigquery_storage.types.ReadSession()
session.name = "projects/test-proj/locations/us/sessions/SOMESESSION"
bqstorage_client.create_read_session.return_value = session
mock_logger = mock.create_autospec(logging.Logger)
@@ -2914,7 +2868,7 @@ def test_to_dataframe_w_bqstorage_logs_session(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_to_dataframe_w_bqstorage_empty_streams(self):
@@ -2930,8 +2884,8 @@ def test_to_dataframe_w_bqstorage_empty_streams(self):
]
arrow_schema = pyarrow.schema(arrow_fields)
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- session = bigquery_storage_v1.types.ReadSession(
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ session = bigquery_storage.types.ReadSession(
streams=[{"name": "/projects/proj/dataset/dset/tables/tbl/streams/1234"}],
arrow_schema={"serialized_schema": arrow_schema.serialize().to_pybytes()},
)
@@ -2969,7 +2923,7 @@ def test_to_dataframe_w_bqstorage_empty_streams(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_to_dataframe_w_bqstorage_nonempty(self):
@@ -2985,8 +2939,8 @@ def test_to_dataframe_w_bqstorage_nonempty(self):
]
arrow_schema = pyarrow.schema(arrow_fields)
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- bqstorage_client.transport = mock.create_autospec(
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ bqstorage_client._transport = mock.create_autospec(
big_query_read_grpc_transport.BigQueryReadGrpcTransport
)
streams = [
@@ -2994,7 +2948,7 @@ def test_to_dataframe_w_bqstorage_nonempty(self):
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/1234"},
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/5678"},
]
- session = bigquery_storage_v1.types.ReadSession(
+ session = bigquery_storage.types.ReadSession(
streams=streams,
arrow_schema={"serialized_schema": arrow_schema.serialize().to_pybytes()},
)
@@ -3045,103 +2999,11 @@ def test_to_dataframe_w_bqstorage_nonempty(self):
self.assertEqual(len(got.index), total_rows)
# Don't close the client if it was passed in.
- bqstorage_client.transport.channel.close.assert_not_called()
-
- @unittest.skipIf(pandas is None, "Requires `pandas`")
- @unittest.skipIf(
- bigquery_storage_v1beta1 is None, "Requires `google-cloud-bigquery-storage`"
- )
- @unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
- def test_to_dataframe_w_bqstorage_v1beta1_nonempty(self):
- from google.cloud.bigquery import schema
- from google.cloud.bigquery import table as mut
- from google.cloud.bigquery_storage_v1beta1 import reader
-
- arrow_fields = [
- pyarrow.field("colA", pyarrow.int64()),
- # Not alphabetical to test column order.
- pyarrow.field("colC", pyarrow.float64()),
- pyarrow.field("colB", pyarrow.utf8()),
- ]
- arrow_schema = pyarrow.schema(arrow_fields)
-
- bqstorage_client = mock.create_autospec(
- bigquery_storage_v1beta1.BigQueryStorageClient
- )
- bqstorage_client.transport = mock.create_autospec(
- big_query_storage_grpc_transport_v1beta1.BigQueryStorageGrpcTransport
- )
- streams = [
- # Use two streams we want to check frames are read from each stream.
- {"name": "/projects/proj/dataset/dset/tables/tbl/streams/1234"},
- {"name": "/projects/proj/dataset/dset/tables/tbl/streams/5678"},
- ]
- session = bigquery_storage_v1beta1.types.ReadSession(
- streams=streams,
- arrow_schema={"serialized_schema": arrow_schema.serialize().to_pybytes()},
- )
- bqstorage_client.create_read_session.return_value = session
-
- mock_rowstream = mock.create_autospec(reader.ReadRowsStream)
- bqstorage_client.read_rows.return_value = mock_rowstream
-
- mock_rows = mock.create_autospec(reader.ReadRowsIterable)
- mock_rowstream.rows.return_value = mock_rows
- page_items = [
- pyarrow.array([1, -1]),
- pyarrow.array([2.0, 4.0]),
- pyarrow.array(["abc", "def"]),
- ]
- page_record_batch = pyarrow.RecordBatch.from_arrays(
- page_items, schema=arrow_schema
- )
- mock_page = mock.create_autospec(reader.ReadRowsPage)
- mock_page.to_arrow.return_value = page_record_batch
- mock_pages = (mock_page, mock_page, mock_page)
- type(mock_rows).pages = mock.PropertyMock(return_value=mock_pages)
-
- schema = [
- schema.SchemaField("colA", "IGNORED"),
- schema.SchemaField("colC", "IGNORED"),
- schema.SchemaField("colB", "IGNORED"),
- ]
-
- row_iterator = mut.RowIterator(
- _mock_client(),
- None, # api_request: ignored
- None, # path: ignored
- schema,
- table=mut.TableReference.from_string("proj.dset.tbl"),
- selected_fields=schema,
- )
-
- with warnings.catch_warnings(record=True) as warned:
- got = row_iterator.to_dataframe(bqstorage_client=bqstorage_client)
-
- # Was a deprecation warning emitted?
- expected_warnings = [
- warning
- for warning in warned
- if issubclass(warning.category, DeprecationWarning)
- and "v1beta1" in str(warning)
- ]
- self.assertEqual(len(expected_warnings), 1, "Deprecation warning not raised.")
-
- # Are the columns in the expected order?
- column_names = ["colA", "colC", "colB"]
- self.assertEqual(list(got), column_names)
-
- # Have expected number of rows?
- total_pages = len(streams) * len(mock_pages)
- total_rows = len(page_items[0]) * total_pages
- self.assertEqual(len(got.index), total_rows)
-
- # Don't close the client if it was passed in.
- bqstorage_client.transport.channel.close.assert_not_called()
+ bqstorage_client._transport.grpc_channel.close.assert_not_called()
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_to_dataframe_w_bqstorage_multiple_streams_return_unique_index(self):
@@ -3156,12 +3018,12 @@ def test_to_dataframe_w_bqstorage_multiple_streams_return_unique_index(self):
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/1234"},
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/5678"},
]
- session = bigquery_storage_v1.types.ReadSession(
+ session = bigquery_storage.types.ReadSession(
streams=streams,
arrow_schema={"serialized_schema": arrow_schema.serialize().to_pybytes()},
)
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
bqstorage_client.create_read_session.return_value = session
mock_rowstream = mock.create_autospec(reader.ReadRowsStream)
@@ -3195,7 +3057,7 @@ def test_to_dataframe_w_bqstorage_multiple_streams_return_unique_index(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(tqdm is None, "Requires `tqdm`")
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
@@ -3211,14 +3073,14 @@ def test_to_dataframe_w_bqstorage_updates_progress_bar(self, tqdm_mock):
arrow_fields = [pyarrow.field("testcol", pyarrow.int64())]
arrow_schema = pyarrow.schema(arrow_fields)
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
streams = [
# Use two streams we want to check that progress bar updates are
# sent from each stream.
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/1234"},
{"name": "/projects/proj/dataset/dset/tables/tbl/streams/5678"},
]
- session = bigquery_storage_v1.types.ReadSession(
+ session = bigquery_storage.types.ReadSession(
streams=streams,
arrow_schema={"serialized_schema": arrow_schema.serialize().to_pybytes()},
)
@@ -3274,7 +3136,7 @@ def blocking_to_arrow(*args, **kwargs):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_to_dataframe_w_bqstorage_exits_on_keyboardinterrupt(self):
@@ -3293,8 +3155,8 @@ def test_to_dataframe_w_bqstorage_exits_on_keyboardinterrupt(self):
]
arrow_schema = pyarrow.schema(arrow_fields)
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- session = bigquery_storage_v1.types.ReadSession(
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ session = bigquery_storage.types.ReadSession(
streams=[
# Use multiple streams because one will fail with a
# KeyboardInterrupt, and we want to check that the other streams
@@ -3393,12 +3255,12 @@ def test_to_dataframe_tabledata_list_w_multiple_pages_return_unique_index(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_dataframe_w_bqstorage_raises_auth_error(self):
from google.cloud.bigquery import table as mut
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
bqstorage_client.create_read_session.side_effect = google.api_core.exceptions.Forbidden(
"TEST BigQuery Storage API not enabled. TEST"
)
@@ -3412,13 +3274,13 @@ def test_to_dataframe_w_bqstorage_raises_auth_error(self):
row_iterator.to_dataframe(bqstorage_client=bqstorage_client)
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_dataframe_w_bqstorage_partition(self):
from google.cloud.bigquery import schema
from google.cloud.bigquery import table as mut
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
row_iterator = mut.RowIterator(
_mock_client(),
@@ -3432,13 +3294,13 @@ def test_to_dataframe_w_bqstorage_partition(self):
row_iterator.to_dataframe(bqstorage_client)
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
def test_to_dataframe_w_bqstorage_snapshot(self):
from google.cloud.bigquery import schema
from google.cloud.bigquery import table as mut
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
row_iterator = mut.RowIterator(
_mock_client(),
@@ -3453,7 +3315,7 @@ def test_to_dataframe_w_bqstorage_snapshot(self):
@unittest.skipIf(pandas is None, "Requires `pandas`")
@unittest.skipIf(
- bigquery_storage_v1 is None, "Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, "Requires `google-cloud-bigquery-storage`"
)
@unittest.skipIf(pyarrow is None, "Requires `pyarrow`")
def test_to_dataframe_concat_categorical_dtype_w_pyarrow(self):
@@ -3472,11 +3334,11 @@ def test_to_dataframe_concat_categorical_dtype_w_pyarrow(self):
arrow_schema = pyarrow.schema(arrow_fields)
# create a mock BQ storage client
- bqstorage_client = mock.create_autospec(bigquery_storage_v1.BigQueryReadClient)
- bqstorage_client.transport = mock.create_autospec(
+ bqstorage_client = mock.create_autospec(bigquery_storage.BigQueryReadClient)
+ bqstorage_client._transport = mock.create_autospec(
big_query_read_grpc_transport.BigQueryReadGrpcTransport
)
- session = bigquery_storage_v1.types.ReadSession(
+ session = bigquery_storage.types.ReadSession(
streams=[{"name": "/projects/proj/dataset/dset/tables/tbl/streams/1234"}],
arrow_schema={"serialized_schema": arrow_schema.serialize().to_pybytes()},
)
@@ -3560,7 +3422,7 @@ def test_to_dataframe_concat_categorical_dtype_w_pyarrow(self):
)
# Don't close the client if it was passed in.
- bqstorage_client.transport.channel.close.assert_not_called()
+ bqstorage_client._transport.grpc_channel.close.assert_not_called()
@unittest.skipIf(pandas is None, "Requires `pandas`")
def test_to_dataframe_concat_categorical_dtype_wo_pyarrow(self):
@@ -4003,7 +3865,7 @@ def test_set_expiration_w_none(self):
@pytest.mark.skipif(
- bigquery_storage_v1 is None, reason="Requires `google-cloud-bigquery-storage`"
+ bigquery_storage is None, reason="Requires `google-cloud-bigquery-storage`"
)
@pytest.mark.parametrize(
"table_path",
@@ -4022,43 +3884,3 @@ def test_table_reference_to_bqstorage_v1_stable(table_path):
for klass in (mut.TableReference, mut.Table, mut.TableListItem):
got = klass.from_string(table_path).to_bqstorage()
assert got == expected
-
-
-@pytest.mark.skipif(
- bigquery_storage_v1beta1 is None, reason="Requires `google-cloud-bigquery-storage`"
-)
-def test_table_reference_to_bqstorage_v1beta1():
- from google.cloud.bigquery import table as mut
-
- # Can't use parametrized pytest because bigquery_storage_v1beta1 may not be
- # available.
- expected = bigquery_storage_v1beta1.types.TableReference(
- project_id="my-project", dataset_id="my_dataset", table_id="my_table"
- )
- cases = (
- "my-project.my_dataset.my_table",
- "my-project.my_dataset.my_table$20181225",
- "my-project.my_dataset.my_table@1234567890",
- "my-project.my_dataset.my_table$20181225@1234567890",
- )
-
- classes = (mut.TableReference, mut.Table, mut.TableListItem)
-
- for case, cls in itertools.product(cases, classes):
- got = cls.from_string(case).to_bqstorage(v1beta1=True)
- assert got == expected
-
-
-@unittest.skipIf(
- bigquery_storage_v1beta1 is None, "Requires `google-cloud-bigquery-storage`"
-)
-def test_table_reference_to_bqstorage_v1beta1_raises_import_error():
- from google.cloud.bigquery import table as mut
-
- classes = (mut.TableReference, mut.Table, mut.TableListItem)
- for cls in classes:
- with mock.patch.object(mut, "bigquery_storage_v1beta1", None), pytest.raises(
- ValueError
- ) as exc_context:
- cls.from_string("my-project.my_dataset.my_table").to_bqstorage(v1beta1=True)
- assert mut._NO_BQSTORAGE_ERROR in str(exc_context.value)