Skip to content

Commit 28d5c67

Browse files
committed
Accept copy jobs with single 'sourceTable' config.
Such jobs would be created via another client: we map that configuration onto a sequence of tables containing only the one item. Closes: #2882.
1 parent 3d354dc commit 28d5c67

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

bigquery/google/cloud/bigquery/job.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,10 @@ def from_api_repr(cls, resource, client):
742742
dataset = Dataset(dest_config['datasetId'], client)
743743
destination = Table(dest_config['tableId'], dataset)
744744
sources = []
745-
for source_config in config['sourceTables']:
745+
source_configs = config.get('sourceTables')
746+
if source_configs is None:
747+
source_configs = [config['sourceTable']]
748+
for source_config in source_configs:
746749
dataset = Dataset(source_config['datasetId'], client)
747750
sources.append(Table(source_config['tableId'], dataset))
748751
job = cls(name, destination, sources, client=client)

bigquery/unit_tests/test_job.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,9 @@ def _verifyResourceProperties(self, job, resource):
675675
self.assertEqual(job.destination.dataset_name, table_ref['datasetId'])
676676
self.assertEqual(job.destination.name, table_ref['tableId'])
677677

678-
sources = config['sourceTables']
678+
sources = config.get('sourceTables')
679+
if sources is None:
680+
sources = [config['sourceTable']]
679681
self.assertEqual(len(sources), len(job.sources))
680682
for table_ref, table in zip(sources, job.sources):
681683
self.assertEqual(table.project, table_ref['projectId'])
@@ -764,6 +766,35 @@ def test_from_api_repr_bare(self):
764766
self.assertIs(job._client, client)
765767
self._verifyResourceProperties(job, RESOURCE)
766768

769+
def test_from_api_repr_w_sourcetable(self):
770+
self._setUpConstants()
771+
client = _Client(self.PROJECT)
772+
RESOURCE = {
773+
'id': self.JOB_ID,
774+
'jobReference': {
775+
'projectId': self.PROJECT,
776+
'jobId': self.JOB_NAME,
777+
},
778+
'configuration': {
779+
'copy': {
780+
'sourceTable': {
781+
'projectId': self.PROJECT,
782+
'datasetId': self.DS_NAME,
783+
'tableId': self.SOURCE_TABLE,
784+
},
785+
'destinationTable': {
786+
'projectId': self.PROJECT,
787+
'datasetId': self.DS_NAME,
788+
'tableId': self.DESTINATION_TABLE,
789+
},
790+
}
791+
},
792+
}
793+
klass = self._get_target_class()
794+
job = klass.from_api_repr(RESOURCE, client=client)
795+
self.assertIs(job._client, client)
796+
self._verifyResourceProperties(job, RESOURCE)
797+
767798
def test_from_api_repr_w_properties(self):
768799
client = _Client(self.PROJECT)
769800
RESOURCE = self._makeResource()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy