|
24 | 24 | from google.cloud import bigquery
|
25 | 25 |
|
26 | 26 | from bigframes import dataframe
|
27 |
| -from bigframes.core import log_adapter |
| 27 | +from bigframes.core import log_adapter, nodes |
28 | 28 | import bigframes.exceptions as bfe
|
29 | 29 | import bigframes.session
|
30 | 30 |
|
@@ -54,7 +54,7 @@ def _curate_df_doc(doc: Optional[str]):
|
54 | 54 |
|
55 | 55 |
|
56 | 56 | class StreamingBase:
|
57 |
| - sql: str |
| 57 | + _appends_sql: str |
58 | 58 | _session: bigframes.session.Session
|
59 | 59 |
|
60 | 60 | def to_bigtable(
|
@@ -124,7 +124,7 @@ def to_bigtable(
|
124 | 124 | can be examined.
|
125 | 125 | """
|
126 | 126 | return _to_bigtable(
|
127 |
| - self.sql, |
| 127 | + self._appends_sql, |
128 | 128 | instance=instance,
|
129 | 129 | table=table,
|
130 | 130 | service_account_email=service_account_email,
|
@@ -181,7 +181,7 @@ def to_pubsub(
|
181 | 181 | can be examined.
|
182 | 182 | """
|
183 | 183 | return _to_pubsub(
|
184 |
| - self.sql, |
| 184 | + self._appends_sql, |
185 | 185 | topic=topic,
|
186 | 186 | service_account_email=service_account_email,
|
187 | 187 | session=self._session,
|
@@ -218,6 +218,19 @@ def __init__(self, df: dataframe.DataFrame, *, create_key=0):
|
218 | 218 | def _from_table_df(cls, df: dataframe.DataFrame) -> StreamingDataFrame:
|
219 | 219 | return cls(df, create_key=cls._create_key)
|
220 | 220 |
|
| 221 | + @property |
| 222 | + def _original_table(self): |
| 223 | + def traverse(node: nodes.BigFrameNode): |
| 224 | + if isinstance(node, nodes.ReadTableNode): |
| 225 | + return f"{node.source.table.project_id}.{node.source.table.dataset_id}.{node.source.table.table_id}" |
| 226 | + for child in node.child_nodes: |
| 227 | + original_table = traverse(child) |
| 228 | + if original_table: |
| 229 | + return original_table |
| 230 | + return None |
| 231 | + |
| 232 | + return traverse(self._df._block._expr.node) |
| 233 | + |
221 | 234 | def __getitem__(self, *args, **kwargs):
|
222 | 235 | return _return_type_wrapper(self._df.__getitem__, StreamingDataFrame)(
|
223 | 236 | *args, **kwargs
|
@@ -266,6 +279,17 @@ def sql(self):
|
266 | 279 |
|
267 | 280 | sql.__doc__ = _curate_df_doc(inspect.getdoc(dataframe.DataFrame.sql))
|
268 | 281 |
|
| 282 | + # Patch for the required APPENDS clause |
| 283 | + @property |
| 284 | + def _appends_sql(self): |
| 285 | + sql_str = self.sql |
| 286 | + original_table = self._original_table |
| 287 | + assert original_table is not None |
| 288 | + |
| 289 | + appends_clause = f"APPENDS(TABLE `{original_table}`, NULL, NULL)" |
| 290 | + sql_str = sql_str.replace(f"`{original_table}`", appends_clause) |
| 291 | + return sql_str |
| 292 | + |
269 | 293 | @property
|
270 | 294 | def _session(self):
|
271 | 295 | return self._df._session
|
|
0 commit comments