File tree Expand file tree Collapse file tree 8 files changed +47
-0
lines changed Expand file tree Collapse file tree 8 files changed +47
-0
lines changed Original file line number Diff line number Diff line change @@ -560,6 +560,7 @@ def do_query():
560
560
num_dml_affected_rows = query_results .num_dml_affected_rows ,
561
561
query = query ,
562
562
total_bytes_processed = query_results .total_bytes_processed ,
563
+ slot_millis = query_results .slot_millis ,
563
564
)
564
565
565
566
if job_retry is not None :
Original file line number Diff line number Diff line change @@ -4144,6 +4144,7 @@ def _list_rows_from_query_results(
4144
4144
num_dml_affected_rows : Optional [int ] = None ,
4145
4145
query : Optional [str ] = None ,
4146
4146
total_bytes_processed : Optional [int ] = None ,
4147
+ slot_millis : Optional [int ] = None ,
4147
4148
) -> RowIterator :
4148
4149
"""List the rows of a completed query.
4149
4150
See
@@ -4195,6 +4196,8 @@ def _list_rows_from_query_results(
4195
4196
The query text used.
4196
4197
total_bytes_processed (Optional[int]):
4197
4198
total bytes processed from job statistics, if present.
4199
+ slot_millis (Optional[int]):
4200
+ Number of slot ms the user is actually billed for.
4198
4201
4199
4202
Returns:
4200
4203
google.cloud.bigquery.table.RowIterator:
@@ -4234,6 +4237,7 @@ def _list_rows_from_query_results(
4234
4237
num_dml_affected_rows = num_dml_affected_rows ,
4235
4238
query = query ,
4236
4239
total_bytes_processed = total_bytes_processed ,
4240
+ slot_millis = slot_millis ,
4237
4241
)
4238
4242
return row_iterator
4239
4243
Original file line number Diff line number Diff line change @@ -1766,6 +1766,7 @@ def is_job_done():
1766
1766
num_dml_affected_rows = self ._query_results .num_dml_affected_rows ,
1767
1767
query = self .query ,
1768
1768
total_bytes_processed = self .total_bytes_processed ,
1769
+ slot_millis = self .slot_millis ,
1769
1770
** list_rows_kwargs ,
1770
1771
)
1771
1772
rows ._preserve_order = _contains_order_by (self .query )
Original file line number Diff line number Diff line change @@ -1282,6 +1282,20 @@ def total_bytes_processed(self):
1282
1282
if total_bytes_processed is not None :
1283
1283
return int (total_bytes_processed )
1284
1284
1285
+ @property
1286
+ def slot_millis (self ):
1287
+ """Total number of slot ms the user is actually billed for.
1288
+
1289
+ See:
1290
+ https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query#body.QueryResponse.FIELDS.slot_millis
1291
+
1292
+ Returns:
1293
+ Optional[int]: Count generated on the server (None until set by the server).
1294
+ """
1295
+ slot_millis = self ._properties .get ("totalSlotMs" )
1296
+ if slot_millis is not None :
1297
+ return int (slot_millis )
1298
+
1285
1299
@property
1286
1300
def num_dml_affected_rows (self ):
1287
1301
"""Total number of rows affected by a DML query.
Original file line number Diff line number Diff line change @@ -1812,6 +1812,7 @@ def __init__(
1812
1812
num_dml_affected_rows : Optional [int ] = None ,
1813
1813
query : Optional [str ] = None ,
1814
1814
total_bytes_processed : Optional [int ] = None ,
1815
+ slot_millis : Optional [int ] = None ,
1815
1816
):
1816
1817
super (RowIterator , self ).__init__ (
1817
1818
client ,
@@ -1841,6 +1842,7 @@ def __init__(
1841
1842
self ._num_dml_affected_rows = num_dml_affected_rows
1842
1843
self ._query = query
1843
1844
self ._total_bytes_processed = total_bytes_processed
1845
+ self ._slot_millis = slot_millis
1844
1846
1845
1847
@property
1846
1848
def _billing_project (self ) -> Optional [str ]:
@@ -1898,6 +1900,11 @@ def total_bytes_processed(self) -> Optional[int]:
1898
1900
"""total bytes processed from job statistics, if present."""
1899
1901
return self ._total_bytes_processed
1900
1902
1903
+ @property
1904
+ def slot_millis (self ) -> Optional [int ]:
1905
+ """Number of slot ms the user is actually billed for."""
1906
+ return self ._slot_millis
1907
+
1901
1908
def _is_almost_completely_cached (self ):
1902
1909
"""Check if all results are completely cached.
1903
1910
Original file line number Diff line number Diff line change @@ -888,6 +888,7 @@ def test_result_reloads_job_state_until_done(self):
888
888
job_resource = self ._make_resource (started = True , location = "EU" )
889
889
job_resource_done = self ._make_resource (started = True , ended = True , location = "EU" )
890
890
job_resource_done ["statistics" ]["query" ]["totalBytesProcessed" ] = str (1234 )
891
+ job_resource_done ["statistics" ]["query" ]["totalSlotMs" ] = str (5678 )
891
892
job_resource_done ["configuration" ]["query" ]["destinationTable" ] = {
892
893
"projectId" : "dest-project" ,
893
894
"datasetId" : "dest_dataset" ,
@@ -969,6 +970,7 @@ def test_result_reloads_job_state_until_done(self):
969
970
self .assertEqual (result .total_rows , 1 )
970
971
self .assertEqual (result .query , job .query )
971
972
self .assertEqual (result .total_bytes_processed , 1234 )
973
+ self .assertEqual (result .slot_millis , 5678 )
972
974
973
975
query_results_path = f"/projects/{ self .PROJECT } /queries/{ self .JOB_ID } "
974
976
query_results_call = mock .call (
Original file line number Diff line number Diff line change @@ -5718,6 +5718,7 @@ def test_query_and_wait_defaults(self):
5718
5718
"rows" : [{"f" : [{"v" : "5552452" }]}],
5719
5719
"queryId" : "job_abcDEF_" ,
5720
5720
"totalBytesProcessed" : 1234 ,
5721
+ "totalSlotMs" : 5678 ,
5721
5722
}
5722
5723
creds = _make_credentials ()
5723
5724
http = object ()
@@ -5735,6 +5736,7 @@ def test_query_and_wait_defaults(self):
5735
5736
self .assertIsNone (rows .location )
5736
5737
self .assertEqual (rows .query , query )
5737
5738
self .assertEqual (rows .total_bytes_processed , 1234 )
5739
+ self .assertEqual (rows .slot_millis , 5678 )
5738
5740
5739
5741
# Verify the request we send is to jobs.query.
5740
5742
conn .api_request .assert_called_once ()
Original file line number Diff line number Diff line change @@ -2000,6 +2000,22 @@ def test_total_bytes_processed_present_string(self):
2000
2000
query = self ._make_one (resource )
2001
2001
self .assertEqual (query .total_bytes_processed , 123456 )
2002
2002
2003
+ def test_slot_millis_missing (self ):
2004
+ query = self ._make_one (self ._make_resource ())
2005
+ self .assertIsNone (query .slot_millis )
2006
+
2007
+ def test_slot_millis_present_integer (self ):
2008
+ resource = self ._make_resource ()
2009
+ resource ["totalSlotMs" ] = 123456
2010
+ query = self ._make_one (resource )
2011
+ self .assertEqual (query .slot_millis , 123456 )
2012
+
2013
+ def test_slot_millis_present_string (self ):
2014
+ resource = self ._make_resource ()
2015
+ resource ["totalSlotMs" ] = "123456"
2016
+ query = self ._make_one (resource )
2017
+ self .assertEqual (query .slot_millis , 123456 )
2018
+
2003
2019
def test_num_dml_affected_rows_missing (self ):
2004
2020
query = self ._make_one (self ._make_resource ())
2005
2021
self .assertIsNone (query .num_dml_affected_rows )
You can’t perform that action at this time.
0 commit comments