Skip to content

Commit 90f1447

Browse files
authored
Move dryRun property to from query to configuration level. (googleapis#2984)
* Move dryRun property to from query to configuration level.
1 parent f5b87a2 commit 90f1447

2 files changed

Lines changed: 68 additions & 25 deletions

File tree

bigquery/google/cloud/bigquery/job.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ def __init__(self, name, query, client,
983983
dry_run = _TypedProperty('dry_run', bool)
984984
"""See:
985985
https://cloud.google.com/bigquery/docs/\
986-
reference/v2/jobs#configuration.query.dryRun
986+
reference/rest/v2/jobs#configuration.dryRun
987987
"""
988988

989989
write_disposition = WriteDisposition('write_disposition')
@@ -1024,8 +1024,6 @@ def _populate_config_resource_booleans(self, configuration):
10241024
configuration['useQueryCache'] = self.use_query_cache
10251025
if self.use_legacy_sql is not None:
10261026
configuration['useLegacySql'] = self.use_legacy_sql
1027-
if self.dry_run is not None:
1028-
configuration['dryRun'] = self.dry_run
10291027

10301028
def _populate_config_resource(self, configuration):
10311029
"""Helper for _build_resource: copy config properties to resource"""
@@ -1078,6 +1076,10 @@ def _build_resource(self):
10781076
},
10791077
},
10801078
}
1079+
1080+
if self.dry_run is not None:
1081+
resource['configuration']['dryRun'] = self.dry_run
1082+
10811083
configuration = resource['configuration'][self._JOB_TYPE]
10821084
self._populate_config_resource(configuration)
10831085

bigquery/unit_tests/test_job.py

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,11 +1331,6 @@ def _verifyBooleanResourceProperties(self, job, config):
13311331
config['useLegacySql'])
13321332
else:
13331333
self.assertIsNone(job.use_legacy_sql)
1334-
if 'dryRun' in config:
1335-
self.assertEqual(job.dry_run,
1336-
config['dryRun'])
1337-
else:
1338-
self.assertIsNone(job.dry_run)
13391334

13401335
def _verifyIntegerResourceProperties(self, job, config):
13411336
if 'maximumBillingTier' in config:
@@ -1366,48 +1361,58 @@ def _verifyQueryParameters(self, job, config):
13661361
for found, expected in zip(job.query_parameters, query_parameters):
13671362
self.assertEqual(found.to_api_repr(), expected)
13681363

1364+
def _verify_configuration_properties(self, job, configuration):
1365+
if 'dryRun' in configuration:
1366+
self.assertEqual(job.dry_run,
1367+
configuration['dryRun'])
1368+
else:
1369+
self.assertIsNone(job.dry_run)
1370+
13691371
def _verifyResourceProperties(self, job, resource):
13701372
self._verifyReadonlyResourceProperties(job, resource)
13711373

1372-
config = resource.get('configuration', {}).get('query')
1373-
self._verifyBooleanResourceProperties(job, config)
1374-
self._verifyIntegerResourceProperties(job, config)
1375-
self._verify_udf_resources(job, config)
1376-
self._verifyQueryParameters(job, config)
1374+
configuration = resource.get('configuration', {})
1375+
self._verify_configuration_properties(job, configuration)
13771376

1378-
self.assertEqual(job.query, config['query'])
1379-
if 'createDisposition' in config:
1377+
query_config = resource.get('configuration', {}).get('query')
1378+
self._verifyBooleanResourceProperties(job, query_config)
1379+
self._verifyIntegerResourceProperties(job, query_config)
1380+
self._verify_udf_resources(job, query_config)
1381+
self._verifyQueryParameters(job, query_config)
1382+
1383+
self.assertEqual(job.query, query_config['query'])
1384+
if 'createDisposition' in query_config:
13801385
self.assertEqual(job.create_disposition,
1381-
config['createDisposition'])
1386+
query_config['createDisposition'])
13821387
else:
13831388
self.assertIsNone(job.create_disposition)
1384-
if 'defaultDataset' in config:
1389+
if 'defaultDataset' in query_config:
13851390
dataset = job.default_dataset
13861391
ds_ref = {
13871392
'projectId': dataset.project,
13881393
'datasetId': dataset.name,
13891394
}
1390-
self.assertEqual(ds_ref, config['defaultDataset'])
1395+
self.assertEqual(ds_ref, query_config['defaultDataset'])
13911396
else:
13921397
self.assertIsNone(job.default_dataset)
1393-
if 'destinationTable' in config:
1398+
if 'destinationTable' in query_config:
13941399
table = job.destination
13951400
tb_ref = {
13961401
'projectId': table.project,
13971402
'datasetId': table.dataset_name,
13981403
'tableId': table.name
13991404
}
1400-
self.assertEqual(tb_ref, config['destinationTable'])
1405+
self.assertEqual(tb_ref, query_config['destinationTable'])
14011406
else:
14021407
self.assertIsNone(job.destination)
1403-
if 'priority' in config:
1408+
if 'priority' in query_config:
14041409
self.assertEqual(job.priority,
1405-
config['priority'])
1410+
query_config['priority'])
14061411
else:
14071412
self.assertIsNone(job.priority)
1408-
if 'writeDisposition' in config:
1413+
if 'writeDisposition' in query_config:
14091414
self.assertEqual(job.write_disposition,
1410-
config['writeDisposition'])
1415+
query_config['writeDisposition'])
14111416
else:
14121417
self.assertIsNone(job.write_disposition)
14131418

@@ -1575,7 +1580,6 @@ def test_begin_w_alternate_client(self):
15751580
'priority': 'INTERACTIVE',
15761581
'useQueryCache': True,
15771582
'useLegacySql': True,
1578-
'dryRun': True,
15791583
'writeDisposition': 'WRITE_TRUNCATE',
15801584
'maximumBillingTier': 4,
15811585
'maximumBytesBilled': 123456
@@ -1599,6 +1603,7 @@ def test_begin_w_alternate_client(self):
15991603
job.use_query_cache = True
16001604
job.use_legacy_sql = True
16011605
job.dry_run = True
1606+
RESOURCE['configuration']['dryRun'] = True
16021607
job.write_disposition = 'WRITE_TRUNCATE'
16031608
job.maximum_billing_tier = 4
16041609
job.maximum_bytes_billed = 123456
@@ -1616,6 +1621,7 @@ def test_begin_w_alternate_client(self):
16161621
'jobId': self.JOB_NAME,
16171622
},
16181623
'configuration': {
1624+
'dryRun': True,
16191625
'query': QUERY_CONFIGURATION,
16201626
},
16211627
}
@@ -1775,6 +1781,41 @@ def test_begin_w_positional_query_parameter(self):
17751781
self.assertEqual(req['data'], SENT)
17761782
self._verifyResourceProperties(job, RESOURCE)
17771783

1784+
def test_dry_run_query(self):
1785+
PATH = '/projects/%s/jobs' % (self.PROJECT,)
1786+
RESOURCE = self._makeResource()
1787+
# Ensure None for missing server-set props
1788+
del RESOURCE['statistics']['creationTime']
1789+
del RESOURCE['etag']
1790+
del RESOURCE['selfLink']
1791+
del RESOURCE['user_email']
1792+
conn = _Connection(RESOURCE)
1793+
client = _Client(project=self.PROJECT, connection=conn)
1794+
job = self._make_one(self.JOB_NAME, self.QUERY, client)
1795+
job.dry_run = True
1796+
RESOURCE['configuration']['dryRun'] = True
1797+
1798+
job.begin()
1799+
self.assertEqual(job.udf_resources, [])
1800+
self.assertEqual(len(conn._requested), 1)
1801+
req = conn._requested[0]
1802+
self.assertEqual(req['method'], 'POST')
1803+
self.assertEqual(req['path'], PATH)
1804+
SENT = {
1805+
'jobReference': {
1806+
'projectId': self.PROJECT,
1807+
'jobId': self.JOB_NAME,
1808+
},
1809+
'configuration': {
1810+
'query': {
1811+
'query': self.QUERY
1812+
},
1813+
'dryRun': True,
1814+
},
1815+
}
1816+
self.assertEqual(req['data'], SENT)
1817+
self._verifyResourceProperties(job, RESOURCE)
1818+
17781819
def test_exists_miss_w_bound_client(self):
17791820
PATH = '/projects/%s/jobs/%s' % (self.PROJECT, self.JOB_NAME)
17801821
conn = _Connection()

0 commit comments

Comments
 (0)