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

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

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)