Skip to content

Commit 729322c

Browse files
yu-iskwLinchin
andauthored
feat: add property for maxStaleness in table definitions (#2087)
* feat: add property for maxStaleness in table definitions Signed-off-by: Yu Ishikawa <[email protected]> * Update google/cloud/bigquery/table.py --------- Signed-off-by: Yu Ishikawa <[email protected]> Co-authored-by: Lingqing Gan <[email protected]>
1 parent 3359ef3 commit 729322c

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

google/cloud/bigquery/table.py

+35
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ class Table(_TableBase):
407407
"view_query": "view",
408408
"require_partition_filter": "requirePartitionFilter",
409409
"table_constraints": "tableConstraints",
410+
"max_staleness": "maxStaleness",
410411
}
411412

412413
def __init__(self, table_ref, schema=None) -> None:
@@ -1115,6 +1116,40 @@ def __repr__(self):
11151116
def __str__(self):
11161117
return f"{self.project}.{self.dataset_id}.{self.table_id}"
11171118

1119+
@property
1120+
def max_staleness(self):
1121+
"""Union[str, None]: The maximum staleness of data that could be returned when the table is queried.
1122+
1123+
Staleness encoded as a string encoding of sql IntervalValue type.
1124+
This property is optional and defaults to None.
1125+
1126+
According to the BigQuery API documentation, maxStaleness specifies the maximum time
1127+
interval for which stale data can be returned when querying the table.
1128+
It helps control data freshness in scenarios like metadata-cached external tables.
1129+
1130+
Returns:
1131+
Optional[str]: A string representing the maximum staleness interval
1132+
(e.g., '1h', '30m', '15s' for hours, minutes, seconds respectively).
1133+
"""
1134+
return self._properties.get(self._PROPERTY_TO_API_FIELD["max_staleness"])
1135+
1136+
@max_staleness.setter
1137+
def max_staleness(self, value):
1138+
"""Set the maximum staleness for the table.
1139+
1140+
Args:
1141+
value (Optional[str]): A string representing the maximum staleness interval.
1142+
Must be a valid time interval string.
1143+
Examples include '1h' (1 hour), '30m' (30 minutes), '15s' (15 seconds).
1144+
1145+
Raises:
1146+
ValueError: If the value is not None and not a string.
1147+
"""
1148+
if value is not None and not isinstance(value, str):
1149+
raise ValueError("max_staleness must be a string or None")
1150+
1151+
self._properties[self._PROPERTY_TO_API_FIELD["max_staleness"]] = value
1152+
11181153

11191154
class TableListItem(_TableBase):
11201155
"""A read-only table resource from a list operation.

tests/unit/test_table.py

+43
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,49 @@ def test___str__(self):
14751475
table1 = self._make_one(TableReference(dataset, "table1"))
14761476
self.assertEqual(str(table1), "project1.dataset1.table1")
14771477

1478+
def test_max_staleness_getter(self):
1479+
"""Test getting max_staleness property."""
1480+
dataset = DatasetReference("test-project", "test_dataset")
1481+
table_ref = dataset.table("test_table")
1482+
table = self._make_one(table_ref)
1483+
# Initially None
1484+
self.assertIsNone(table.max_staleness)
1485+
# Set max_staleness using setter
1486+
table.max_staleness = "1h"
1487+
self.assertEqual(table.max_staleness, "1h")
1488+
1489+
def test_max_staleness_setter(self):
1490+
"""Test setting max_staleness property."""
1491+
dataset = DatasetReference("test-project", "test_dataset")
1492+
table_ref = dataset.table("test_table")
1493+
table = self._make_one(table_ref)
1494+
# Set valid max_staleness
1495+
table.max_staleness = "30m"
1496+
self.assertEqual(table.max_staleness, "30m")
1497+
# Set to None
1498+
table.max_staleness = None
1499+
self.assertIsNone(table.max_staleness)
1500+
1501+
def test_max_staleness_setter_invalid_type(self):
1502+
"""Test setting max_staleness with an invalid type raises ValueError."""
1503+
dataset = DatasetReference("test-project", "test_dataset")
1504+
table_ref = dataset.table("test_table")
1505+
table = self._make_one(table_ref)
1506+
# Try setting invalid type
1507+
with self.assertRaises(ValueError):
1508+
table.max_staleness = 123 # Not a string
1509+
1510+
def test_max_staleness_to_api_repr(self):
1511+
"""Test max_staleness is correctly represented in API representation."""
1512+
dataset = DatasetReference("test-project", "test_dataset")
1513+
table_ref = dataset.table("test_table")
1514+
table = self._make_one(table_ref)
1515+
# Set max_staleness
1516+
table.max_staleness = "1h"
1517+
# Convert to API representation
1518+
resource = table.to_api_repr()
1519+
self.assertEqual(resource.get("maxStaleness"), "1h")
1520+
14781521

14791522
class Test_row_from_mapping(unittest.TestCase, _SchemaBase):
14801523
PROJECT = "prahj-ekt"

0 commit comments

Comments
 (0)