Skip to content

Commit 601e984

Browse files
authored
fix: access MATERIALIZED_VIEW with read_gbq (#1070)
* fix: corrected inability to access MATERIALIZED_VIEW with read_gbq * update test
1 parent 067fa08 commit 601e984

File tree

5 files changed

+34
-6
lines changed

5 files changed

+34
-6
lines changed

bigframes/core/nodes.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ class GbqTable:
547547
table_id: str = field()
548548
physical_schema: Tuple[bq.SchemaField, ...] = field()
549549
n_rows: int = field()
550-
is_physical_table: bool = field()
550+
is_physically_stored: bool = field()
551551
cluster_cols: typing.Optional[Tuple[str, ...]]
552552

553553
@staticmethod
@@ -563,7 +563,7 @@ def from_table(table: bq.Table, columns: Sequence[str] = ()) -> GbqTable:
563563
table_id=table.table_id,
564564
physical_schema=schema,
565565
n_rows=table.num_rows,
566-
is_physical_table=(table.table_type == "TABLE"),
566+
is_physically_stored=(table.table_type in ["TABLE", "MATERIALIZED_VIEW"]),
567567
cluster_cols=None
568568
if table.clustering_fields is None
569569
else tuple(table.clustering_fields),
@@ -641,7 +641,7 @@ def variables_introduced(self) -> int:
641641

642642
@property
643643
def row_count(self) -> typing.Optional[int]:
644-
if self.source.sql_predicate is None and self.source.table.is_physical_table:
644+
if self.source.sql_predicate is None and self.source.table.is_physically_stored:
645645
return self.source.table.n_rows
646646
return None
647647

bigframes/session/_io/bigquery/read_gbq_table.py

+12
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ def validate_table(
102102
table_ref: bigquery.table.TableReference,
103103
columns: Optional[Sequence[str]],
104104
snapshot_time: datetime.datetime,
105+
table_type: str,
105106
filter_str: Optional[str] = None,
106107
) -> bool:
107108
"""Validates that the table can be read, returns True iff snapshot is supported."""
@@ -124,6 +125,17 @@ def validate_table(
124125
if table_ref.dataset_id.startswith("_"):
125126
return False
126127

128+
# Materialized views,does not support snapshot
129+
if table_type == "MATERIALIZED_VIEW":
130+
warnings.warn(
131+
"Materialized views do not support FOR SYSTEM_TIME AS OF queries. "
132+
"Attempting query without time travel. Be aware that as materialized views "
133+
"are updated periodically, modifications to the underlying data in the view may "
134+
"result in errors or unexpected behavior.",
135+
category=bigframes.exceptions.TimeTravelDisabledWarning,
136+
)
137+
return False
138+
127139
# Second, try with snapshot to verify table supports this feature
128140
snapshot_sql = bigframes.session._io.bigquery.to_query(
129141
query_or_table=f"{table_ref.project}.{table_ref.dataset_id}.{table_ref.table_id}",

bigframes/session/loader.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,12 @@ def read_gbq_table(
339339
)
340340

341341
enable_snapshot = enable_snapshot and bf_read_gbq_table.validate_table(
342-
self._bqclient, table_ref, all_columns, time_travel_timestamp, filter_str
342+
self._bqclient,
343+
table_ref,
344+
all_columns,
345+
time_travel_timestamp,
346+
table.table_type,
347+
filter_str,
343348
)
344349

345350
# ----------------------------

tests/system/small/test_dataframe.py

+4
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,10 @@ def test_shape(scalars_dfs):
15241524
@pytest.mark.parametrize(
15251525
"reference_table, test_table",
15261526
[
1527+
(
1528+
"bigframes-dev.bigframes_tests_sys.base_table",
1529+
"bigframes-dev.bigframes_tests_sys.base_table_mat_view",
1530+
),
15271531
(
15281532
"bigframes-dev.bigframes_tests_sys.base_table",
15291533
"bigframes-dev.bigframes_tests_sys.base_table_view",

tests/system/small/test_session.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,16 @@ def test_read_gbq_twice_with_same_timestamp(session, penguins_table_id):
390390
assert df3 is not None
391391

392392

393-
def test_read_gbq_on_linked_dataset_warns(session):
393+
@pytest.mark.parametrize(
394+
"source_table",
395+
[
396+
"bigframes-dev.thelook_ecommerce.orders",
397+
"bigframes-dev.bigframes_tests_sys.base_table_mat_view",
398+
],
399+
)
400+
def test_read_gbq_on_linked_dataset_warns(session, source_table):
394401
with warnings.catch_warnings(record=True) as warned:
395-
session.read_gbq("bigframes-dev.thelook_ecommerce.orders")
402+
session.read_gbq(source_table)
396403
assert len(warned) == 1
397404
assert warned[0].category == bigframes.exceptions.TimeTravelDisabledWarning
398405

0 commit comments

Comments
 (0)