Skip to content

Commit 2d5f932

Browse files
authored
feat: add query text and total bytes processed to RowIterator (#2140)
1 parent f8572dd commit 2d5f932

File tree

6 files changed

+36
-0
lines changed

6 files changed

+36
-0
lines changed

google/cloud/bigquery/_job_helpers.py

+2
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,8 @@ def do_query():
526526
query_id=query_results.query_id,
527527
project=query_results.project,
528528
num_dml_affected_rows=query_results.num_dml_affected_rows,
529+
query=query,
530+
total_bytes_processed=query_results.total_bytes_processed,
529531
)
530532

531533
if job_retry is not None:

google/cloud/bigquery/client.py

+8
Original file line numberDiff line numberDiff line change
@@ -4081,6 +4081,8 @@ def _list_rows_from_query_results(
40814081
query_id: Optional[str] = None,
40824082
first_page_response: Optional[Dict[str, Any]] = None,
40834083
num_dml_affected_rows: Optional[int] = None,
4084+
query: Optional[str] = None,
4085+
total_bytes_processed: Optional[int] = None,
40844086
) -> RowIterator:
40854087
"""List the rows of a completed query.
40864088
See
@@ -4128,6 +4130,10 @@ def _list_rows_from_query_results(
41284130
num_dml_affected_rows (Optional[int]):
41294131
If this RowIterator is the result of a DML query, the number of
41304132
rows that were affected.
4133+
query (Optional[str]):
4134+
The query text used.
4135+
total_bytes_processed (Optinal[int]):
4136+
total bytes processed from job statistics, if present.
41314137
41324138
Returns:
41334139
google.cloud.bigquery.table.RowIterator:
@@ -4165,6 +4171,8 @@ def _list_rows_from_query_results(
41654171
query_id=query_id,
41664172
first_page_response=first_page_response,
41674173
num_dml_affected_rows=num_dml_affected_rows,
4174+
query=query,
4175+
total_bytes_processed=total_bytes_processed,
41684176
)
41694177
return row_iterator
41704178

google/cloud/bigquery/job/query.py

+2
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,8 @@ def is_job_done():
17411741
query_id=self.query_id,
17421742
first_page_response=first_page_response,
17431743
num_dml_affected_rows=self._query_results.num_dml_affected_rows,
1744+
query=self.query,
1745+
total_bytes_processed=self.total_bytes_processed,
17441746
**list_rows_kwargs,
17451747
)
17461748
rows._preserve_order = _contains_order_by(self.query)

google/cloud/bigquery/table.py

+18
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,10 @@ class RowIterator(HTTPIterator):
17601760
first_page_response (Optional[dict]):
17611761
API response for the first page of results. These are returned when
17621762
the first page is requested.
1763+
query (Optional[str]):
1764+
The query text used.
1765+
total_bytes_processed (Optinal[int]):
1766+
total bytes processed from job statistics, if present.
17631767
"""
17641768

17651769
def __init__(
@@ -1781,6 +1785,8 @@ def __init__(
17811785
query_id: Optional[str] = None,
17821786
project: Optional[str] = None,
17831787
num_dml_affected_rows: Optional[int] = None,
1788+
query: Optional[str] = None,
1789+
total_bytes_processed: Optional[int] = None,
17841790
):
17851791
super(RowIterator, self).__init__(
17861792
client,
@@ -1808,6 +1814,8 @@ def __init__(
18081814
self._query_id = query_id
18091815
self._project = project
18101816
self._num_dml_affected_rows = num_dml_affected_rows
1817+
self._query = query
1818+
self._total_bytes_processed = total_bytes_processed
18111819

18121820
@property
18131821
def _billing_project(self) -> Optional[str]:
@@ -1855,6 +1863,16 @@ def query_id(self) -> Optional[str]:
18551863
"""
18561864
return self._query_id
18571865

1866+
@property
1867+
def query(self) -> Optional[str]:
1868+
"""The query text used."""
1869+
return self._query
1870+
1871+
@property
1872+
def total_bytes_processed(self) -> Optional[int]:
1873+
"""total bytes processed from job statistics, if present."""
1874+
return self._total_bytes_processed
1875+
18581876
def _is_almost_completely_cached(self):
18591877
"""Check if all results are completely cached.
18601878

tests/unit/job/test_query.py

+3
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ def test_result_reloads_job_state_until_done(self):
887887
}
888888
job_resource = self._make_resource(started=True, location="EU")
889889
job_resource_done = self._make_resource(started=True, ended=True, location="EU")
890+
job_resource_done["statistics"]["query"]["totalBytesProcessed"] = str(1234)
890891
job_resource_done["configuration"]["query"]["destinationTable"] = {
891892
"projectId": "dest-project",
892893
"datasetId": "dest_dataset",
@@ -966,6 +967,8 @@ def test_result_reloads_job_state_until_done(self):
966967
# Test that the total_rows property has changed during iteration, based
967968
# on the response from tabledata.list.
968969
self.assertEqual(result.total_rows, 1)
970+
self.assertEqual(result.query, job.query)
971+
self.assertEqual(result.total_bytes_processed, 1234)
969972

970973
query_results_path = f"/projects/{self.PROJECT}/queries/{self.JOB_ID}"
971974
query_results_call = mock.call(

tests/unit/test_client.py

+3
Original file line numberDiff line numberDiff line change
@@ -5517,6 +5517,7 @@ def test_query_and_wait_defaults(self):
55175517
"totalRows": "1",
55185518
"rows": [{"f": [{"v": "5552452"}]}],
55195519
"queryId": "job_abcDEF_",
5520+
"totalBytesProcessed": 1234,
55205521
}
55215522
creds = _make_credentials()
55225523
http = object()
@@ -5532,6 +5533,8 @@ def test_query_and_wait_defaults(self):
55325533
self.assertIsNone(rows.job_id)
55335534
self.assertIsNone(rows.project)
55345535
self.assertIsNone(rows.location)
5536+
self.assertEqual(rows.query, query)
5537+
self.assertEqual(rows.total_bytes_processed, 1234)
55355538

55365539
# Verify the request we send is to jobs.query.
55375540
conn.api_request.assert_called_once()

0 commit comments

Comments
 (0)