|
58 | 58 | from google.cloud.bigquery.model import ModelReference
|
59 | 59 | from google.cloud.bigquery.query import _QueryResults
|
60 | 60 | from google.cloud.bigquery.retry import DEFAULT_RETRY
|
| 61 | +from google.cloud.bigquery.routine import Routine |
| 62 | +from google.cloud.bigquery.routine import RoutineReference |
61 | 63 | from google.cloud.bigquery.schema import SchemaField
|
62 | 64 | from google.cloud.bigquery.table import _table_arg_to_table
|
63 | 65 | from google.cloud.bigquery.table import _table_arg_to_table_ref
|
@@ -374,6 +376,41 @@ def create_dataset(self, dataset, exists_ok=False, retry=DEFAULT_RETRY):
|
374 | 376 | raise
|
375 | 377 | return self.get_dataset(dataset.reference, retry=retry)
|
376 | 378 |
|
| 379 | + def create_routine(self, routine, exists_ok=False, retry=DEFAULT_RETRY): |
| 380 | + """[Beta] Create a routine via a POST request. |
| 381 | +
|
| 382 | + See |
| 383 | + https://cloud.google.com/bigquery/docs/reference/rest/v2/routines/insert |
| 384 | +
|
| 385 | + Args: |
| 386 | + routine (:class:`~google.cloud.bigquery.routine.Routine`): |
| 387 | + A :class:`~google.cloud.bigquery.routine.Routine` to create. |
| 388 | + The dataset that the routine belongs to must already exist. |
| 389 | + exists_ok (bool): |
| 390 | + Defaults to ``False``. If ``True``, ignore "already exists" |
| 391 | + errors when creating the routine. |
| 392 | + retry (google.api_core.retry.Retry): |
| 393 | + Optional. How to retry the RPC. |
| 394 | +
|
| 395 | + Returns: |
| 396 | + google.cloud.bigquery.routine.Routine: |
| 397 | + A new ``Routine`` returned from the service. |
| 398 | + """ |
| 399 | + reference = routine.reference |
| 400 | + path = "/projects/{}/datasets/{}/routines".format( |
| 401 | + reference.project, reference.dataset_id |
| 402 | + ) |
| 403 | + resource = routine.to_api_repr() |
| 404 | + try: |
| 405 | + api_response = self._call_api( |
| 406 | + retry, method="POST", path=path, data=resource |
| 407 | + ) |
| 408 | + return Routine.from_api_repr(api_response) |
| 409 | + except google.api_core.exceptions.Conflict: |
| 410 | + if not exists_ok: |
| 411 | + raise |
| 412 | + return self.get_routine(routine.reference, retry=retry) |
| 413 | + |
377 | 414 | def create_table(self, table, exists_ok=False, retry=DEFAULT_RETRY):
|
378 | 415 | """API call: create a table via a PUT request
|
379 | 416 |
|
@@ -472,6 +509,34 @@ def get_model(self, model_ref, retry=DEFAULT_RETRY):
|
472 | 509 | api_response = self._call_api(retry, method="GET", path=model_ref.path)
|
473 | 510 | return Model.from_api_repr(api_response)
|
474 | 511 |
|
| 512 | + def get_routine(self, routine_ref, retry=DEFAULT_RETRY): |
| 513 | + """[Beta] Get the routine referenced by ``routine_ref``. |
| 514 | +
|
| 515 | + Args: |
| 516 | + routine_ref (Union[ \ |
| 517 | + :class:`~google.cloud.bigquery.routine.Routine`, \ |
| 518 | + :class:`~google.cloud.bigquery.routine.RoutineReference`, \ |
| 519 | + str, \ |
| 520 | + ]): |
| 521 | + A reference to the routine to fetch from the BigQuery API. If |
| 522 | + a string is passed in, this method attempts to create a |
| 523 | + reference from a string using |
| 524 | + :func:`google.cloud.bigquery.routine.RoutineReference.from_string`. |
| 525 | + retry (:class:`google.api_core.retry.Retry`): |
| 526 | + (Optional) How to retry the API call. |
| 527 | +
|
| 528 | + Returns: |
| 529 | + google.cloud.bigquery.routine.Routine: |
| 530 | + A ``Routine`` instance. |
| 531 | + """ |
| 532 | + if isinstance(routine_ref, str): |
| 533 | + routine_ref = RoutineReference.from_string( |
| 534 | + routine_ref, default_project=self.project |
| 535 | + ) |
| 536 | + |
| 537 | + api_response = self._call_api(retry, method="GET", path=routine_ref.path) |
| 538 | + return Routine.from_api_repr(api_response) |
| 539 | + |
475 | 540 | def get_table(self, table, retry=DEFAULT_RETRY):
|
476 | 541 | """Fetch the table referenced by ``table``.
|
477 | 542 |
|
@@ -537,7 +602,7 @@ def update_model(self, model, fields, retry=DEFAULT_RETRY):
|
537 | 602 |
|
538 | 603 | Use ``fields`` to specify which fields to update. At least one field
|
539 | 604 | must be provided. If a field is listed in ``fields`` and is ``None``
|
540 |
| - in ``model``, it will be deleted. |
| 605 | + in ``model``, the field value will be deleted. |
541 | 606 |
|
542 | 607 | If ``model.etag`` is not ``None``, the update will only succeed if
|
543 | 608 | the model on the server has the same ETag. Thus reading a model with
|
@@ -567,12 +632,58 @@ def update_model(self, model, fields, retry=DEFAULT_RETRY):
|
567 | 632 | )
|
568 | 633 | return Model.from_api_repr(api_response)
|
569 | 634 |
|
| 635 | + def update_routine(self, routine, fields, retry=DEFAULT_RETRY): |
| 636 | + """[Beta] Change some fields of a routine. |
| 637 | +
|
| 638 | + Use ``fields`` to specify which fields to update. At least one field |
| 639 | + must be provided. If a field is listed in ``fields`` and is ``None`` |
| 640 | + in ``routine``, the field value will be deleted. |
| 641 | +
|
| 642 | + .. warning:: |
| 643 | + During beta, partial updates are not supported. You must provide |
| 644 | + all fields in the resource. |
| 645 | +
|
| 646 | + If :attr:`~google.cloud.bigquery.routine.Routine.etag` is not |
| 647 | + ``None``, the update will only succeed if the resource on the server |
| 648 | + has the same ETag. Thus reading a routine with |
| 649 | + :func:`~google.cloud.bigquery.client.Client.get_routine`, changing |
| 650 | + its fields, and then passing it to this method will ensure that the |
| 651 | + changes will only be saved if no modifications to the resource |
| 652 | + occurred since the read. |
| 653 | +
|
| 654 | + Args: |
| 655 | + routine (google.cloud.bigquery.routine.Routine): The routine to update. |
| 656 | + fields (Sequence[str]): |
| 657 | + The fields of ``routine`` to change, spelled as the |
| 658 | + :class:`~google.cloud.bigquery.routine.Routine` properties |
| 659 | + (e.g. ``type_``). |
| 660 | + retry (google.api_core.retry.Retry): |
| 661 | + (Optional) A description of how to retry the API call. |
| 662 | +
|
| 663 | + Returns: |
| 664 | + google.cloud.bigquery.routine.Routine: |
| 665 | + The routine resource returned from the API call. |
| 666 | + """ |
| 667 | + partial = routine._build_resource(fields) |
| 668 | + if routine.etag: |
| 669 | + headers = {"If-Match": routine.etag} |
| 670 | + else: |
| 671 | + headers = None |
| 672 | + |
| 673 | + # TODO: remove when routines update supports partial requests. |
| 674 | + partial["routineReference"] = routine.reference.to_api_repr() |
| 675 | + |
| 676 | + api_response = self._call_api( |
| 677 | + retry, method="PUT", path=routine.path, data=partial, headers=headers |
| 678 | + ) |
| 679 | + return Routine.from_api_repr(api_response) |
| 680 | + |
570 | 681 | def update_table(self, table, fields, retry=DEFAULT_RETRY):
|
571 | 682 | """Change some fields of a table.
|
572 | 683 |
|
573 | 684 | Use ``fields`` to specify which fields to update. At least one field
|
574 | 685 | must be provided. If a field is listed in ``fields`` and is ``None``
|
575 |
| - in ``table``, it will be deleted. |
| 686 | + in ``table``, the field value will be deleted. |
576 | 687 |
|
577 | 688 | If ``table.etag`` is not ``None``, the update will only succeed if
|
578 | 689 | the table on the server has the same ETag. Thus reading a table with
|
@@ -660,6 +771,64 @@ def list_models(
|
660 | 771 | result.dataset = dataset
|
661 | 772 | return result
|
662 | 773 |
|
| 774 | + def list_routines( |
| 775 | + self, dataset, max_results=None, page_token=None, retry=DEFAULT_RETRY |
| 776 | + ): |
| 777 | + """[Beta] List routines in the dataset. |
| 778 | +
|
| 779 | + See |
| 780 | + https://cloud.google.com/bigquery/docs/reference/rest/v2/routines/list |
| 781 | +
|
| 782 | + Args: |
| 783 | + dataset (Union[ \ |
| 784 | + :class:`~google.cloud.bigquery.dataset.Dataset`, \ |
| 785 | + :class:`~google.cloud.bigquery.dataset.DatasetReference`, \ |
| 786 | + str, \ |
| 787 | + ]): |
| 788 | + A reference to the dataset whose routines to list from the |
| 789 | + BigQuery API. If a string is passed in, this method attempts |
| 790 | + to create a dataset reference from a string using |
| 791 | + :func:`google.cloud.bigquery.dataset.DatasetReference.from_string`. |
| 792 | + max_results (int): |
| 793 | + (Optional) Maximum number of routines to return. If not passed, |
| 794 | + defaults to a value set by the API. |
| 795 | + page_token (str): |
| 796 | + (Optional) Token representing a cursor into the routines. If |
| 797 | + not passed, the API will return the first page of routines. The |
| 798 | + token marks the beginning of the iterator to be returned and |
| 799 | + the value of the ``page_token`` can be accessed at |
| 800 | + ``next_page_token`` of the |
| 801 | + :class:`~google.api_core.page_iterator.HTTPIterator`. |
| 802 | + retry (:class:`google.api_core.retry.Retry`): |
| 803 | + (Optional) How to retry the RPC. |
| 804 | +
|
| 805 | + Returns: |
| 806 | + google.api_core.page_iterator.Iterator: |
| 807 | + Iterator of all |
| 808 | + :class:`~google.cloud.bigquery.routine.Routine`s contained |
| 809 | + within the requested dataset, limited by ``max_results``. |
| 810 | + """ |
| 811 | + if isinstance(dataset, str): |
| 812 | + dataset = DatasetReference.from_string( |
| 813 | + dataset, default_project=self.project |
| 814 | + ) |
| 815 | + |
| 816 | + if not isinstance(dataset, (Dataset, DatasetReference)): |
| 817 | + raise TypeError("dataset must be a Dataset, DatasetReference, or string") |
| 818 | + |
| 819 | + path = "{}/routines".format(dataset.path) |
| 820 | + result = page_iterator.HTTPIterator( |
| 821 | + client=self, |
| 822 | + api_request=functools.partial(self._call_api, retry), |
| 823 | + path=path, |
| 824 | + item_to_value=_item_to_routine, |
| 825 | + items_key="routines", |
| 826 | + page_token=page_token, |
| 827 | + max_results=max_results, |
| 828 | + ) |
| 829 | + result.dataset = dataset |
| 830 | + return result |
| 831 | + |
663 | 832 | def list_tables(
|
664 | 833 | self, dataset, max_results=None, page_token=None, retry=DEFAULT_RETRY
|
665 | 834 | ):
|
@@ -800,6 +969,42 @@ def delete_model(self, model, retry=DEFAULT_RETRY, not_found_ok=False):
|
800 | 969 | if not not_found_ok:
|
801 | 970 | raise
|
802 | 971 |
|
| 972 | + def delete_routine(self, routine, retry=DEFAULT_RETRY, not_found_ok=False): |
| 973 | + """[Beta] Delete a routine. |
| 974 | +
|
| 975 | + See |
| 976 | + https://cloud.google.com/bigquery/docs/reference/rest/v2/routines/delete |
| 977 | +
|
| 978 | + Args: |
| 979 | + model (Union[ \ |
| 980 | + :class:`~google.cloud.bigquery.routine.Routine`, \ |
| 981 | + :class:`~google.cloud.bigquery.routine.RoutineReference`, \ |
| 982 | + str, \ |
| 983 | + ]): |
| 984 | + A reference to the routine to delete. If a string is passed |
| 985 | + in, this method attempts to create a routine reference from a |
| 986 | + string using |
| 987 | + :func:`google.cloud.bigquery.routine.RoutineReference.from_string`. |
| 988 | + retry (:class:`google.api_core.retry.Retry`): |
| 989 | + (Optional) How to retry the RPC. |
| 990 | + not_found_ok (bool): |
| 991 | + Defaults to ``False``. If ``True``, ignore "not found" errors |
| 992 | + when deleting the routine. |
| 993 | + """ |
| 994 | + if isinstance(routine, str): |
| 995 | + routine = RoutineReference.from_string( |
| 996 | + routine, default_project=self.project |
| 997 | + ) |
| 998 | + |
| 999 | + if not isinstance(routine, (Routine, RoutineReference)): |
| 1000 | + raise TypeError("routine must be a Routine or a RoutineReference") |
| 1001 | + |
| 1002 | + try: |
| 1003 | + self._call_api(retry, method="DELETE", path=routine.path) |
| 1004 | + except google.api_core.exceptions.NotFound: |
| 1005 | + if not not_found_ok: |
| 1006 | + raise |
| 1007 | + |
803 | 1008 | def delete_table(self, table, retry=DEFAULT_RETRY, not_found_ok=False):
|
804 | 1009 | """Delete a table
|
805 | 1010 |
|
@@ -2073,6 +2278,21 @@ def _item_to_model(iterator, resource):
|
2073 | 2278 | return Model.from_api_repr(resource)
|
2074 | 2279 |
|
2075 | 2280 |
|
| 2281 | +def _item_to_routine(iterator, resource): |
| 2282 | + """Convert a JSON model to the native object. |
| 2283 | +
|
| 2284 | + Args: |
| 2285 | + iterator (google.api_core.page_iterator.Iterator): |
| 2286 | + The iterator that is currently in use. |
| 2287 | + resource (dict): |
| 2288 | + An item to be converted to a routine. |
| 2289 | +
|
| 2290 | + Returns: |
| 2291 | + google.cloud.bigquery.routine.Routine: The next routine in the page. |
| 2292 | + """ |
| 2293 | + return Routine.from_api_repr(resource) |
| 2294 | + |
| 2295 | + |
2076 | 2296 | def _item_to_table(iterator, resource):
|
2077 | 2297 | """Convert a JSON table to the native object.
|
2078 | 2298 |
|
|
0 commit comments