Skip to content

Commit d158cc7

Browse files
authored
Merge pull request #2884 from tseaver/2882-bigquery-copyjob-w-single-source-table
Accept copy jobs with single 'sourceTable' config.
2 parents becf0a2 + f003e0f commit d158cc7

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

bigquery/google/cloud/bigquery/job.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,14 @@ 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+
single = config.get('sourceTable')
748+
if single is None:
749+
raise KeyError(
750+
"Resource missing 'sourceTables' / 'sourceTable'")
751+
source_configs = [single]
752+
for source_config in source_configs:
746753
dataset = Dataset(source_config['datasetId'], client)
747754
sources.append(Table(source_config['tableId'], dataset))
748755
job = cls(name, destination, sources, client=client)

bigquery/unit_tests/test_job.py

Lines changed: 55 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,58 @@ 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+
798+
def test_from_api_repr_wo_sources(self):
799+
self._setUpConstants()
800+
client = _Client(self.PROJECT)
801+
RESOURCE = {
802+
'id': self.JOB_ID,
803+
'jobReference': {
804+
'projectId': self.PROJECT,
805+
'jobId': self.JOB_NAME,
806+
},
807+
'configuration': {
808+
'copy': {
809+
'destinationTable': {
810+
'projectId': self.PROJECT,
811+
'datasetId': self.DS_NAME,
812+
'tableId': self.DESTINATION_TABLE,
813+
},
814+
}
815+
},
816+
}
817+
klass = self._get_target_class()
818+
with self.assertRaises(KeyError):
819+
klass.from_api_repr(RESOURCE, client=client)
820+
767821
def test_from_api_repr_w_properties(self):
768822
client = _Client(self.PROJECT)
769823
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