Source code for google.cloud.bigquery.routine

# -*- coding: utf-8 -*-
#
# Copyright 2019 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.

"""Define resources for the BigQuery Routines API."""

from google.protobuf import json_format
import six

import google.cloud._helpers
from google.cloud.bigquery import _helpers
import google.cloud.bigquery_v2.types


[docs]class Routine(object): """Resource representing a user-defined routine. See https://cloud.google.com/bigquery/docs/reference/rest/v2/routines Args: routine_ref (Union[ \ str, \ google.cloud.bigquery.routine.RoutineReference, \ ]): A pointer to a routine. If ``routine_ref`` is a string, it must included a project ID, dataset ID, and routine ID, each separated by ``.``. ``**kwargs`` (Dict): Initial property values. """ _PROPERTY_TO_API_FIELD = { "arguments": "arguments", "body": "definitionBody", "created": "creationTime", "etag": "etag", "imported_libraries": "importedLibraries", "language": "language", "modified": "lastModifiedTime", "reference": "routineReference", "return_type": "returnType", "type_": "routineType", } def __init__(self, routine_ref, **kwargs): if isinstance(routine_ref, six.string_types): routine_ref = RoutineReference.from_string(routine_ref) self._properties = {"routineReference": routine_ref.to_api_repr()} for property_name in kwargs: setattr(self, property_name, kwargs[property_name]) @property def reference(self): """google.cloud.bigquery.routine.RoutineReference: Reference describing the ID of this routine. """ return RoutineReference.from_api_repr( self._properties[self._PROPERTY_TO_API_FIELD["reference"]] ) @property def path(self): """str: URL path for the routine's APIs.""" return self.reference.path @property def project(self): """str: ID of the project containing the routine.""" return self.reference.project @property def dataset_id(self): """str: ID of dataset containing the routine.""" return self.reference.dataset_id @property def routine_id(self): """str: The routine ID.""" return self.reference.routine_id @property def etag(self): """str: ETag for the resource (:data:`None` until set from the server). Read-only. """ return self._properties.get(self._PROPERTY_TO_API_FIELD["etag"]) @property def type_(self): """str: The fine-grained type of the routine. See: https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#RoutineType """ return self._properties.get(self._PROPERTY_TO_API_FIELD["type_"]) @type_.setter def type_(self, value): self._properties[self._PROPERTY_TO_API_FIELD["type_"]] = value @property def created(self): """Optional[datetime.datetime]: Datetime at which the routine was created (:data:`None` until set from the server). Read-only. """ value = self._properties.get(self._PROPERTY_TO_API_FIELD["created"]) if value is not None and value != 0: # value will be in milliseconds. return google.cloud._helpers._datetime_from_microseconds( 1000.0 * float(value) ) @property def modified(self): """Optional[datetime.datetime]: Datetime at which the routine was last modified (:data:`None` until set from the server). Read-only. """ value = self._properties.get(self._PROPERTY_TO_API_FIELD["modified"]) if value is not None and value != 0: # value will be in milliseconds. return google.cloud._helpers._datetime_from_microseconds( 1000.0 * float(value) ) @property def language(self): """Optional[str]: The language of the routine. Defaults to ``SQL``. """ return self._properties.get(self._PROPERTY_TO_API_FIELD["language"]) @language.setter def language(self, value): self._properties[self._PROPERTY_TO_API_FIELD["language"]] = value @property def arguments(self): """List[google.cloud.bigquery.routine.RoutineArgument]: Input/output argument of a function or a stored procedure. In-place modification is not supported. To set, replace the entire property value with the modified list of :class:`~google.cloud.bigquery.routine.RoutineArgument` objects. """ resources = self._properties.get(self._PROPERTY_TO_API_FIELD["arguments"], []) return [RoutineArgument.from_api_repr(resource) for resource in resources] @arguments.setter def arguments(self, value): if not value: resource = [] else: resource = [argument.to_api_repr() for argument in value] self._properties[self._PROPERTY_TO_API_FIELD["arguments"]] = resource @property def return_type(self): """google.cloud.bigquery_v2.types.StandardSqlDataType: Return type of the routine. If absent, the return type is inferred from :attr:`~google.cloud.bigquery.routine.Routine.body` at query time in each query that references this routine. If present, then the evaluated result will be cast to the specified returned type at query time. See: https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#resource-routine """ 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 @return_type.setter def return_type(self, value): if value: resource = json_format.MessageToDict(value) else: resource = None self._properties[self._PROPERTY_TO_API_FIELD["return_type"]] = resource @property def imported_libraries(self): """List[str]: The path of the imported JavaScript libraries. The :attr:`~google.cloud.bigquery.routine.Routine.language` must equal ``JAVACRIPT``. Examples: Set the ``imported_libraries`` to a list of Google Cloud Storage URIs. .. code-block:: python routine = bigquery.Routine("proj.dataset.routine_id") routine.imported_libraries = [ "gs://cloud-samples-data/bigquery/udfs/max-value.js", ] """ return self._properties.get( self._PROPERTY_TO_API_FIELD["imported_libraries"], [] ) @imported_libraries.setter def imported_libraries(self, value): if not value: resource = [] else: resource = value self._properties[self._PROPERTY_TO_API_FIELD["imported_libraries"]] = resource @property def body(self): """str: The body of the routine.""" return self._properties.get(self._PROPERTY_TO_API_FIELD["body"]) @body.setter def body(self, value): self._properties[self._PROPERTY_TO_API_FIELD["body"]] = value
[docs] @classmethod def from_api_repr(cls, resource): """Factory: construct a routine given its API representation. Args: resource (Dict[str, object]): Resource, as returned from the API. Returns: google.cloud.bigquery.routine.Routine: Python object, as parsed from ``resource``. """ ref = cls(RoutineReference.from_api_repr(resource["routineReference"])) ref._properties = resource return ref
[docs] def to_api_repr(self): """Construct the API resource representation of this routine. Returns: Dict[str, object]: Routine represented as an API resource. """ return self._properties
def _build_resource(self, filter_fields): """Generate a resource for ``update``.""" return _helpers._build_resource_from_properties(self, filter_fields) def __repr__(self): return "Routine('{}.{}.{}')".format( self.project, self.dataset_id, self.routine_id )
[docs]class RoutineArgument(object): """Input/output argument of a function or a stored procedure. See https://cloud.google.com/bigquery/docs/reference/rest/v2/routines Args: ``**kwargs`` (Dict): Initial property values. """ _PROPERTY_TO_API_FIELD = { "data_type": "dataType", "kind": "argumentKind", # Even though it's not necessary for field mapping to map when the # property name equals the resource name, we add these here so that we # have an exhaustive list of all properties. "name": "name", "mode": "mode", } def __init__(self, **kwargs): self._properties = {} for property_name in kwargs: setattr(self, property_name, kwargs[property_name]) @property def name(self): """Optional[str]: Name of this argument. Can be absent for function return argument. """ return self._properties.get(self._PROPERTY_TO_API_FIELD["name"]) @name.setter def name(self, value): self._properties[self._PROPERTY_TO_API_FIELD["name"]] = value @property def kind(self): """Optional[str]: The kind of argument, for example ``FIXED_TYPE`` or ``ANY_TYPE``. See: https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#ArgumentKind """ return self._properties.get(self._PROPERTY_TO_API_FIELD["kind"]) @kind.setter def kind(self, value): self._properties[self._PROPERTY_TO_API_FIELD["kind"]] = value @property def mode(self): """Optional[str]: The input/output mode of the argument.""" return self._properties.get(self._PROPERTY_TO_API_FIELD["mode"]) @mode.setter def mode(self, value): self._properties[self._PROPERTY_TO_API_FIELD["mode"]] = value @property def data_type(self): """Optional[google.cloud.bigquery_v2.types.StandardSqlDataType]: Type of a variable, e.g., a function argument. See: https://cloud.google.com/bigquery/docs/reference/rest/v2/StandardSqlDataType """ 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 @data_type.setter def data_type(self, value): if value: resource = json_format.MessageToDict(value) else: resource = None self._properties[self._PROPERTY_TO_API_FIELD["data_type"]] = resource
[docs] @classmethod def from_api_repr(cls, resource): """Factory: construct a routine argument given its API representation. Args: resource (Dict[str, object]): Resource, as returned from the API. Returns: google.cloud.bigquery.routine.RoutineArgument: Python object, as parsed from ``resource``. """ ref = cls() ref._properties = resource return ref
[docs] def to_api_repr(self): """Construct the API resource representation of this routine argument. Returns: Dict[str, object]: Routine argument represented as an API resource. """ return self._properties
def __eq__(self, other): if not isinstance(other, RoutineArgument): return NotImplemented return self._properties == other._properties def __ne__(self, other): return not self == other def __repr__(self): all_properties = [ "{}={}".format(property_name, repr(getattr(self, property_name))) for property_name in sorted(self._PROPERTY_TO_API_FIELD) ] return "RoutineArgument({})".format(", ".join(all_properties))
[docs]class RoutineReference(object): """A pointer to a routine. See https://cloud.google.com/bigquery/docs/reference/rest/v2/routines """ def __init__(self): self._properties = {} @property def project(self): """str: ID of the project containing the routine.""" return self._properties["projectId"] @property def dataset_id(self): """str: ID of dataset containing the routine.""" return self._properties["datasetId"] @property def routine_id(self): """str: The routine ID.""" return self._properties["routineId"] @property def path(self): """str: URL path for the routine's APIs.""" return "/projects/%s/datasets/%s/routines/%s" % ( self.project, self.dataset_id, self.routine_id, )
[docs] @classmethod def from_api_repr(cls, resource): """Factory: construct a routine reference given its API representation. Args: resource (Dict[str, object]): Routine reference representation returned from the API. Returns: google.cloud.bigquery.routine.RoutineReference: Routine reference parsed from ``resource``. """ ref = cls() ref._properties = resource return ref
[docs] @classmethod def from_string(cls, routine_id, default_project=None): """Factory: construct a routine reference from routine ID string. Args: routine_id (str): A routine ID in standard SQL format. If ``default_project`` is not specified, this must included a project ID, dataset ID, and routine ID, each separated by ``.``. default_project (str): Optional. The project ID to use when ``routine_id`` does not include a project ID. Returns: google.cloud.bigquery.routine.RoutineReference: Routine reference parsed from ``routine_id``. Raises: ValueError: If ``routine_id`` is not a fully-qualified routine ID in standard SQL format. """ proj, dset, routine = _helpers._parse_3_part_id( routine_id, default_project=default_project, property_name="routine_id" ) return cls.from_api_repr( {"projectId": proj, "datasetId": dset, "routineId": routine} )
[docs] def to_api_repr(self): """Construct the API resource representation of this routine reference. Returns: Dict[str, object]: Routine reference represented as an API resource. """ return self._properties
def __eq__(self, other): """Two RoutineReferences are equal if they point to the same routine.""" if not isinstance(other, RoutineReference): return NotImplemented return str(self) == str(other) def __hash__(self): return hash(str(self)) def __ne__(self, other): return not self == other def __repr__(self): return "RoutineReference.from_string('{}')".format(str(self)) def __str__(self): """String representation of the reference. This is a fully-qualified ID, including the project ID and dataset ID. """ return "{}.{}.{}".format(self.project, self.dataset_id, self.routine_id)