From dccb36224b5212f830346fb8745737086c048599 Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Tue, 19 Sep 2017 22:23:26 -0400 Subject: [PATCH 1/3] bigquery: add client.delete_dataset --- bigquery/google/cloud/bigquery/client.py | 13 ++++++++-- bigquery/google/cloud/bigquery/dataset.py | 14 ----------- bigquery/tests/system.py | 2 +- bigquery/tests/unit/test_client.py | 13 ++++++++++ bigquery/tests/unit/test_dataset.py | 29 ----------------------- 5 files changed, 25 insertions(+), 46 deletions(-) diff --git a/bigquery/google/cloud/bigquery/client.py b/bigquery/google/cloud/bigquery/client.py index 1f5620f66ca8..7f7105c9f776 100644 --- a/bigquery/google/cloud/bigquery/client.py +++ b/bigquery/google/cloud/bigquery/client.py @@ -243,8 +243,6 @@ def update_dataset(self, dataset, fields): :rtype: :class:`google.cloud.bigquery.dataset.Dataset` :returns: the modified ``Dataset`` instance - :raises: ValueError for fields that cannot be updated. - """ if dataset.project is None: dataset._project = self.project @@ -266,6 +264,17 @@ def update_dataset(self, dataset, fields): method='PATCH', path=path, data=partial, headers=headers) return Dataset.from_api_repr(api_response, self) + def delete_dataset(self, dataset_ref): + """Delete a dataset. + + See + https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/delete + + :type dataset_ref: :class:`~google.cloud.bigquery.dataset.DatasetReference` + :param dataset_ref: a reference to the dataset to delete. + """ + self._connection.api_request(method='DELETE', path=dataset_ref.path) + def _get_query_results(self, job_id, project=None, timeout_ms=None): """Get the query results object for a query job. diff --git a/bigquery/google/cloud/bigquery/dataset.py b/bigquery/google/cloud/bigquery/dataset.py index dabd0a129ec1..5f34989cb587 100644 --- a/bigquery/google/cloud/bigquery/dataset.py +++ b/bigquery/google/cloud/bigquery/dataset.py @@ -488,20 +488,6 @@ def _build_resource(self): return resource - def delete(self, client=None): - """API call: delete the dataset via a DELETE request. - - See - https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/delete - - :type client: :class:`~google.cloud.bigquery.client.Client` or - ``NoneType`` - :param client: the client to use. If not passed, falls back to the - ``client`` stored on the current dataset. - """ - client = self._require_client(client) - client._connection.api_request(method='DELETE', path=self.path) - def list_tables(self, max_results=None, page_token=None): """List tables for the project associated with this client. diff --git a/bigquery/tests/system.py b/bigquery/tests/system.py index 2730ed0d1be2..f20f240d6cb1 100644 --- a/bigquery/tests/system.py +++ b/bigquery/tests/system.py @@ -105,7 +105,7 @@ def _still_in_use(bad_request): if isinstance(doomed, Bucket): retry_409(doomed.delete)(force=True) elif isinstance(doomed, Dataset): - retry_in_use(doomed.delete)() + retry_in_use(Config.CLIENT.delete_dataset)(doomed) else: doomed.delete() diff --git a/bigquery/tests/unit/test_client.py b/bigquery/tests/unit/test_client.py index 173f059374da..c9912681cc2b 100644 --- a/bigquery/tests/unit/test_client.py +++ b/bigquery/tests/unit/test_client.py @@ -480,6 +480,19 @@ def test_update_dataset(self): req = conn._requested[1] self.assertEqual(req['headers']['If-Match'], 'etag') + def test_delete_dataset(self): + PROJECT = 'PROJECT' + DS_ID = 'DATASET_ID' + PATH = 'projects/%s/datasets/%s' % (PROJECT, DS_ID) + creds = _make_credentials() + client = self._make_one(project=PROJECT, credentials=creds) + conn = client._connection = _Connection({}) + client.delete_dataset(client.dataset(DS_ID)) + self.assertEqual(len(conn._requested), 1) + req = conn._requested[0] + self.assertEqual(req['method'], 'DELETE') + self.assertEqual(req['path'], '/%s' % PATH) + def test_job_from_resource_unknown_type(self): PROJECT = 'PROJECT' creds = _make_credentials() diff --git a/bigquery/tests/unit/test_dataset.py b/bigquery/tests/unit/test_dataset.py index 3f2a809955fb..c527f1d79d83 100644 --- a/bigquery/tests/unit/test_dataset.py +++ b/bigquery/tests/unit/test_dataset.py @@ -387,35 +387,6 @@ def test__parse_access_entries_w_extra_keys(self): with self.assertRaises(ValueError): dataset._parse_access_entries(ACCESS) - def test_delete_w_bound_client(self): - PATH = 'projects/%s/datasets/%s' % (self.PROJECT, self.DS_ID) - conn = _Connection({}) - client = _Client(project=self.PROJECT, connection=conn) - dataset = self._make_one(self.DS_ID, client=client) - - dataset.delete() - - self.assertEqual(len(conn._requested), 1) - req = conn._requested[0] - self.assertEqual(req['method'], 'DELETE') - self.assertEqual(req['path'], '/%s' % PATH) - - def test_delete_w_alternate_client(self): - PATH = 'projects/%s/datasets/%s' % (self.PROJECT, self.DS_ID) - conn1 = _Connection() - CLIENT1 = _Client(project=self.PROJECT, connection=conn1) - conn2 = _Connection({}) - CLIENT2 = _Client(project=self.PROJECT, connection=conn2) - dataset = self._make_one(self.DS_ID, client=CLIENT1) - - dataset.delete(client=CLIENT2) - - self.assertEqual(len(conn1._requested), 0) - self.assertEqual(len(conn2._requested), 1) - req = conn2._requested[0] - self.assertEqual(req['method'], 'DELETE') - self.assertEqual(req['path'], '/%s' % PATH) - def test_list_tables_empty(self): import six From 39f8d1e94ea65d6c57de5e701ad4fed02ba238f9 Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Wed, 20 Sep 2017 14:09:21 -0400 Subject: [PATCH 2/3] support Dataset as well as DatasetReference --- bigquery/google/cloud/bigquery/client.py | 13 +++++++++---- bigquery/tests/unit/test_client.py | 23 +++++++++++++++++------ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/bigquery/google/cloud/bigquery/client.py b/bigquery/google/cloud/bigquery/client.py index 7f7105c9f776..940b016645f3 100644 --- a/bigquery/google/cloud/bigquery/client.py +++ b/bigquery/google/cloud/bigquery/client.py @@ -264,16 +264,21 @@ def update_dataset(self, dataset, fields): method='PATCH', path=path, data=partial, headers=headers) return Dataset.from_api_repr(api_response, self) - def delete_dataset(self, dataset_ref): + def delete_dataset(self, dataset): """Delete a dataset. See https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets/delete - :type dataset_ref: :class:`~google.cloud.bigquery.dataset.DatasetReference` - :param dataset_ref: a reference to the dataset to delete. + :type dataset: One of: + :class:`~google.cloud.bigquery.dataset.Dataset` + :class:`~google.cloud.bigquery.dataset.DatasetReference` + + :param dataset: the dataset to delete, or a reference to it. """ - self._connection.api_request(method='DELETE', path=dataset_ref.path) + if not isinstance(dataset, (Dataset, DatasetReference)): + raise TypeError('dataset must be a Dataset or a DatasetReference') + self._connection.api_request(method='DELETE', path=dataset.path) def _get_query_results(self, job_id, project=None, timeout_ms=None): """Get the query results object for a query job. diff --git a/bigquery/tests/unit/test_client.py b/bigquery/tests/unit/test_client.py index c9912681cc2b..2f50ad520988 100644 --- a/bigquery/tests/unit/test_client.py +++ b/bigquery/tests/unit/test_client.py @@ -481,17 +481,28 @@ def test_update_dataset(self): self.assertEqual(req['headers']['If-Match'], 'etag') def test_delete_dataset(self): + from google.cloud.bigquery.dataset import Dataset + PROJECT = 'PROJECT' DS_ID = 'DATASET_ID' PATH = 'projects/%s/datasets/%s' % (PROJECT, DS_ID) creds = _make_credentials() client = self._make_one(project=PROJECT, credentials=creds) - conn = client._connection = _Connection({}) - client.delete_dataset(client.dataset(DS_ID)) - self.assertEqual(len(conn._requested), 1) - req = conn._requested[0] - self.assertEqual(req['method'], 'DELETE') - self.assertEqual(req['path'], '/%s' % PATH) + conn = client._connection = _Connection({}, {}) + for arg in (client.dataset(DS_ID), Dataset(DS_ID, project=PROJECT)): + client.delete_dataset(arg) + req = conn._requested[0] + self.assertEqual(req['method'], 'DELETE') + self.assertEqual(req['path'], '/%s' % PATH) + + def test_delete_dataset_wrong_type(self): + PROJECT = 'PROJECT' + DS_ID = 'DATASET_ID' + PATH = 'projects/%s/datasets/%s' % (PROJECT, DS_ID) + creds = _make_credentials() + client = self._make_one(project=PROJECT, credentials=creds) + with self.assertRaises(TypeError): + client.delete_dataset(client.dataset(DS_ID).table("foo")) def test_job_from_resource_unknown_type(self): PROJECT = 'PROJECT' From 9795a12a68dfcea1b3be3cf0f9517dfcece80294 Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Wed, 20 Sep 2017 14:38:29 -0400 Subject: [PATCH 3/3] fix lint --- bigquery/google/cloud/bigquery/dataset.py | 15 --------------- bigquery/tests/unit/test_client.py | 1 - 2 files changed, 16 deletions(-) diff --git a/bigquery/google/cloud/bigquery/dataset.py b/bigquery/google/cloud/bigquery/dataset.py index 5f34989cb587..0d9198809595 100644 --- a/bigquery/google/cloud/bigquery/dataset.py +++ b/bigquery/google/cloud/bigquery/dataset.py @@ -394,21 +394,6 @@ def from_api_repr(cls, resource, client): dataset._set_properties(resource) return dataset - def _require_client(self, client): - """Check client or verify over-ride. - - :type client: :class:`~google.cloud.bigquery.client.Client` or - ``NoneType`` - :param client: the client to use. If not passed, falls back to the - ``client`` stored on the current dataset. - - :rtype: :class:`google.cloud.bigquery.client.Client` - :returns: The client passed in or the currently bound client. - """ - if client is None: - client = self._client - return client - @staticmethod def _parse_access_entries(access): """Parse a resource fragment into a set of access entries. diff --git a/bigquery/tests/unit/test_client.py b/bigquery/tests/unit/test_client.py index 2f50ad520988..ceb530d5a134 100644 --- a/bigquery/tests/unit/test_client.py +++ b/bigquery/tests/unit/test_client.py @@ -498,7 +498,6 @@ def test_delete_dataset(self): def test_delete_dataset_wrong_type(self): PROJECT = 'PROJECT' DS_ID = 'DATASET_ID' - PATH = 'projects/%s/datasets/%s' % (PROJECT, DS_ID) creds = _make_credentials() client = self._make_one(project=PROJECT, credentials=creds) with self.assertRaises(TypeError):