Skip to content

Commit b3d9b07

Browse files
committed
BQ: use a string or list of string for client.extract_table.
This will match behavior of copy_table and remove the need for special formatting of the keyword arguments.
1 parent fd691a2 commit b3d9b07

File tree

2 files changed

+70
-15
lines changed

2 files changed

+70
-15
lines changed

bigquery/google/cloud/bigquery/client.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,9 @@ def copy_table(self, sources, destination, job_id=None, job_config=None,
832832
job.begin(retry=retry)
833833
return job
834834

835-
def extract_table(self, source, *destination_uris, **kwargs):
835+
def extract_table(
836+
self, source, destination_uris, job_config=None, job_id=None,
837+
retry=DEFAULT_RETRY):
836838
"""Start a job to extract a table into Cloud Storage files.
837839
838840
See
@@ -841,33 +843,35 @@ def extract_table(self, source, *destination_uris, **kwargs):
841843
:type source: :class:`google.cloud.bigquery.table.TableReference`
842844
:param source: table to be extracted.
843845
844-
:type destination_uris: sequence of string
846+
:type destination_uris: One of:
847+
str or
848+
sequence of str
845849
:param destination_uris:
846850
URIs of Cloud Storage file(s) into which table data is to be
847851
extracted; in format ``gs://<bucket_name>/<object_name_or_glob>``.
848852
849853
:type kwargs: dict
850854
:param kwargs: Additional keyword arguments.
851855
852-
:Keyword Arguments:
853-
* *job_config*
854-
(:class:`google.cloud.bigquery.job.ExtractJobConfig`) --
855-
(Optional) Extra configuration options for the extract job.
856-
* *job_id* (``str``) --
857-
Additional content
858-
(Optional) The ID of the job.
859-
* *retry* (:class:`google.api.core.retry.Retry`)
860-
(Optional) How to retry the RPC.
856+
:type job_id: str
857+
:param job_id: (Optional) The ID of the job.
858+
859+
:type job_config: :class:`google.cloud.bigquery.job.ExtractJobConfig`
860+
:param job_config: (Optional) Extra configuration options for the job.
861+
862+
:type retry: :class:`google.api.core.retry.Retry`
863+
:param retry: (Optional) How to retry the RPC.
861864
862865
:rtype: :class:`google.cloud.bigquery.job.ExtractJob`
863866
:returns: a new ``ExtractJob`` instance
864867
"""
865-
job_config = kwargs.get('job_config')
866-
job_id = _make_job_id(kwargs.get('job_id'))
867-
retry = kwargs.get('retry', DEFAULT_RETRY)
868+
job_id = _make_job_id(job_id)
869+
870+
if isinstance(destination_uris, six.string_types):
871+
destination_uris = [destination_uris]
868872

869873
job = ExtractJob(
870-
job_id, source, list(destination_uris), client=self,
874+
job_id, source, destination_uris, client=self,
871875
job_config=job_config)
872876
job.begin(retry=retry)
873877
return job

bigquery/tests/unit/test_client.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,57 @@ def test_extract_table_generated_job_id(self):
17031703
self.assertEqual(job.source, source)
17041704
self.assertEqual(list(job.destination_uris), [DESTINATION])
17051705

1706+
def test_extract_table_w_destination_uris(self):
1707+
from google.cloud.bigquery.job import ExtractJob
1708+
1709+
JOB = 'job_id'
1710+
SOURCE = 'source_table'
1711+
DESTINATION1 = 'gs://bucket_name/object_one'
1712+
DESTINATION2 = 'gs://bucket_name/object_two'
1713+
RESOURCE = {
1714+
'jobReference': {
1715+
'projectId': self.PROJECT,
1716+
'jobId': JOB,
1717+
},
1718+
'configuration': {
1719+
'extract': {
1720+
'sourceTable': {
1721+
'projectId': self.PROJECT,
1722+
'datasetId': self.DS_ID,
1723+
'tableId': SOURCE,
1724+
},
1725+
'destinationUris': [
1726+
DESTINATION1,
1727+
DESTINATION2,
1728+
],
1729+
},
1730+
},
1731+
}
1732+
creds = _make_credentials()
1733+
http = object()
1734+
client = self._make_one(project=self.PROJECT, credentials=creds,
1735+
_http=http)
1736+
conn = client._connection = _Connection(RESOURCE)
1737+
dataset = client.dataset(self.DS_ID)
1738+
source = dataset.table(SOURCE)
1739+
1740+
job = client.extract_table(
1741+
source, [DESTINATION1, DESTINATION2], job_id=JOB)
1742+
1743+
# Check that extract_table actually starts the job.
1744+
self.assertEqual(len(conn._requested), 1)
1745+
req = conn._requested[0]
1746+
self.assertEqual(req['method'], 'POST')
1747+
self.assertEqual(req['path'], '/projects/PROJECT/jobs')
1748+
1749+
# Check the job resource.
1750+
self.assertIsInstance(job, ExtractJob)
1751+
self.assertIs(job._client, client)
1752+
self.assertEqual(job.job_id, JOB)
1753+
self.assertEqual(job.source, source)
1754+
self.assertEqual(
1755+
list(job.destination_uris), [DESTINATION1, DESTINATION2])
1756+
17061757
def test_query_defaults(self):
17071758
from google.cloud.bigquery.job import QueryJob
17081759

0 commit comments

Comments
 (0)