Skip to content

Commit 1b79e9b

Browse files
committed
refactor and testing
1 parent 290daec commit 1b79e9b

File tree

3 files changed

+82
-68
lines changed

3 files changed

+82
-68
lines changed

google/cloud/bigquery/job/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,5 @@
8585
"SourceFormat",
8686
"TransactionInfo",
8787
"WriteDisposition",
88+
"IncrementalResultStats",
8889
]

google/cloud/bigquery/job/query.py

Lines changed: 64 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,66 @@ def from_api_repr(cls, stats: Dict[str, str]) -> "DmlStats":
197197
return cls(*args)
198198

199199

200+
class IncrementalResultStats:
201+
"""IncrementalResultStats provides information about incremental query execution."""
202+
203+
def __init__(self):
204+
self._properties = {}
205+
206+
@classmethod
207+
def from_api_repr(cls, resource) -> "IncrementalResultStats":
208+
"""Factory: construct instance from the JSON repr.
209+
210+
Args:
211+
resource(Dict[str: object]):
212+
IncrementalResultStats representation returned from API.
213+
214+
Returns:
215+
google.cloud.bigquery.job.IncrementalResultStats:
216+
stats parsed from ``resource``.
217+
"""
218+
entry = cls()
219+
entry._properties = resource
220+
return entry
221+
222+
@property
223+
def disabled_reason(self):
224+
"""Optional[string]: Reason why incremental results were not
225+
written by the query.
226+
"""
227+
return _helpers._str_or_none(self._properties.get("disabledReason"))
228+
229+
@property
230+
def result_set_last_replace_time(self):
231+
"""Optional[datetime]: The time at which the result table's contents
232+
were completely replaced. May be absent if no results have been written
233+
or the query has completed."""
234+
from google.cloud._helpers import _rfc3339_nanos_to_datetime
235+
236+
value = self._properties.get("resultSetLastReplaceTime")
237+
if value:
238+
try:
239+
return _rfc3339_nanos_to_datetime(value)
240+
except ValueError:
241+
pass
242+
return None
243+
244+
@property
245+
def result_set_last_modify_time(self):
246+
"""Optional[datetime]: The time at which the result table's contents
247+
were completely replaced. May be absent if no results have been written
248+
or the query has completed."""
249+
from google.cloud._helpers import _rfc3339_nanos_to_datetime
250+
251+
value = self._properties.get("resultSetLastModifyTime")
252+
if value:
253+
try:
254+
return _rfc3339_nanos_to_datetime(value)
255+
except ValueError:
256+
pass
257+
return None
258+
259+
200260
class IndexUnusedReason(typing.NamedTuple):
201261
"""Reason about why no search index was used in the search query (or sub-query).
202262
@@ -1340,15 +1400,11 @@ def bi_engine_stats(self) -> Optional[BiEngineStats]:
13401400
return BiEngineStats.from_api_repr(stats)
13411401

13421402
@property
1343-
def incremental_result_stats(self):
1344-
"""Optional[google.cloud.bigquery.job.IncrementalResultStats]: return information about incremental query results.
1345-
1346-
This feature is not generally available.
1347-
"""
1403+
def incremental_result_stats(self) -> Optional[IncrementalResultStats]:
13481404
stats = self._job_statistics().get("incrementalResultStats")
1349-
if stats is not None:
1350-
prop = IncrementalResultStats.from_api_repr(stats)
1351-
return None
1405+
if stats is None:
1406+
return None
1407+
return IncrementalResultStats.from_api_repr(stats)
13521408

13531409
def _blocking_poll(self, timeout=None, **kwargs):
13541410
self._done_timeout = timeout
@@ -2576,63 +2632,3 @@ def slot_millis(self):
25762632
"""Optional[int]: Cumulative slot-milliseconds consumed by
25772633
this query."""
25782634
return _helpers._int_or_none(self._properties.get("totalSlotMs"))
2579-
2580-
2581-
class IncrementalResultStats(object):
2582-
"""IncrementalResultStats provides information about incremental query execution."""
2583-
2584-
def __init__(self):
2585-
self._properties = {}
2586-
2587-
@classmethod
2588-
def from_api_repr(cls, resource):
2589-
"""Factory: construct instance from the JSON repr.
2590-
2591-
Args:
2592-
resource(Dict[str: object]):
2593-
QueryTimelineSample representation returned from API.
2594-
2595-
Returns:
2596-
google.cloud.bigquery.TimelineEntry:
2597-
Timeline sample parsed from ``resource``.
2598-
"""
2599-
entry = cls()
2600-
entry._properties = resource
2601-
return entry
2602-
2603-
@property
2604-
def disabled_reason(self):
2605-
"""Optional[string]: Reason why incremental reasons were not
2606-
written by the query.
2607-
"""
2608-
return _helpers._str_or_none(self._properties.get("disabledReason"))
2609-
2610-
@property
2611-
def result_set_last_replace_time(self):
2612-
"""Optional[datetime]: The time at which the result table's contents
2613-
were completely replaced. May be absent if no results have been written
2614-
or the query has completed."""
2615-
from google.cloud._helpers import _rfc3339_nanos_to_datetime
2616-
2617-
value = self._properties.get("resultSetLastReplaceTime")
2618-
if value:
2619-
try:
2620-
return _rfc3339_nanos_to_datetime(value)
2621-
except ValueError:
2622-
pass
2623-
return None
2624-
2625-
@property
2626-
def result_set_last_modify_time(self):
2627-
"""Optional[datetime]: The time at which the result table's contents
2628-
were completely replaced. May be absent if no results have been written
2629-
or the query has completed."""
2630-
from google.cloud._helpers import _rfc3339_nanos_to_datetime
2631-
2632-
value = self._properties.get("resultSetLastModifyTime")
2633-
if value:
2634-
try:
2635-
return _rfc3339_nanos_to_datetime(value)
2636-
except ValueError:
2637-
pass
2638-
return None

tests/unit/job/test_query.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,23 @@ def test_search_stats(self):
838838
assert isinstance(job.search_stats, SearchStats)
839839
assert job.search_stats.mode == "INDEX_USAGE_MODE_UNSPECIFIED"
840840

841+
def test_incremental_result_stats(self):
842+
from google.cloud.bigquery.job.query import IncrementalResultStats
843+
844+
client = _make_client(project=self.PROJECT)
845+
job = self._make_one(self.JOB_ID, self.QUERY, client)
846+
assert job.incremental_result_stats is None
847+
848+
statistics = job._properties["statistics"] = {}
849+
assert job.incremental_result_stats is None
850+
851+
query_stats = statistics["query"] = {}
852+
assert job.incremental_result_stats is None
853+
854+
query_stats["incrementalResultStats"] = {"disabledReason": "BAZ"}
855+
assert isinstance(job.incremental_result_stats, IncrementalResultStats)
856+
assert job.incremental_result_stats.disabled_reason == "BAZ"
857+
841858
def test_reload_query_results_uses_transport_timeout(self):
842859
conn = make_connection({})
843860
client = _make_client(self.PROJECT, connection=conn)

0 commit comments

Comments
 (0)