|
24 | 24 | SourceQuery, |
25 | 25 | set_catalog, |
26 | 26 | ) |
| 27 | +from sqlmesh.utils.date import TimeLike |
27 | 28 |
|
28 | 29 | if t.TYPE_CHECKING: |
29 | 30 | from trino.dbapi import Connection as TrinoConnection |
30 | 31 |
|
31 | 32 | from sqlmesh.core._typing import SchemaName, TableName |
32 | | - from sqlmesh.core.engine_adapter._typing import DF |
| 33 | + from sqlmesh.core.engine_adapter._typing import DF, QueryOrDF |
33 | 34 |
|
34 | 35 |
|
35 | 36 | @set_catalog() |
@@ -183,3 +184,80 @@ def _df_to_source_queries( |
183 | 184 | df[column] = pd.to_datetime(df[column]).map(lambda x: x.isoformat(" ")) # type: ignore |
184 | 185 |
|
185 | 186 | return super()._df_to_source_queries(df, columns_to_types, batch_size, target_table) |
| 187 | + |
| 188 | + def _build_schema_exp( |
| 189 | + self, |
| 190 | + table: exp.Table, |
| 191 | + columns_to_types: t.Dict[str, exp.DataType], |
| 192 | + column_descriptions: t.Optional[t.Dict[str, str]] = None, |
| 193 | + expressions: t.Optional[t.List[exp.PrimaryKey]] = None, |
| 194 | + is_view: bool = False, |
| 195 | + ) -> exp.Schema: |
| 196 | + if self.current_catalog_type == "delta_lake": |
| 197 | + columns_to_types = self._to_delta_ts(columns_to_types) |
| 198 | + |
| 199 | + return super()._build_schema_exp( |
| 200 | + table, columns_to_types, column_descriptions, expressions, is_view |
| 201 | + ) |
| 202 | + |
| 203 | + def _scd_type_2( |
| 204 | + self, |
| 205 | + target_table: TableName, |
| 206 | + source_table: QueryOrDF, |
| 207 | + unique_key: t.Sequence[exp.Expression], |
| 208 | + valid_from_name: str, |
| 209 | + valid_to_name: str, |
| 210 | + execution_time: TimeLike, |
| 211 | + invalidate_hard_deletes: bool = True, |
| 212 | + updated_at_name: t.Optional[str] = None, |
| 213 | + check_columns: t.Optional[t.Union[exp.Star, t.Sequence[exp.Column]]] = None, |
| 214 | + updated_at_as_valid_from: bool = False, |
| 215 | + execution_time_as_valid_from: bool = False, |
| 216 | + columns_to_types: t.Optional[t.Dict[str, exp.DataType]] = None, |
| 217 | + table_description: t.Optional[str] = None, |
| 218 | + column_descriptions: t.Optional[t.Dict[str, str]] = None, |
| 219 | + ) -> None: |
| 220 | + if columns_to_types and self.current_catalog_type == "delta_lake": |
| 221 | + columns_to_types = self._to_delta_ts(columns_to_types) |
| 222 | + |
| 223 | + return super()._scd_type_2( |
| 224 | + target_table, |
| 225 | + source_table, |
| 226 | + unique_key, |
| 227 | + valid_from_name, |
| 228 | + valid_to_name, |
| 229 | + execution_time, |
| 230 | + invalidate_hard_deletes, |
| 231 | + updated_at_name, |
| 232 | + check_columns, |
| 233 | + updated_at_as_valid_from, |
| 234 | + execution_time_as_valid_from, |
| 235 | + columns_to_types, |
| 236 | + table_description, |
| 237 | + column_descriptions, |
| 238 | + ) |
| 239 | + |
| 240 | + # delta_lake only supports two timestamp data types. This method converts other |
| 241 | + # timestamp types to those two for use in DDL statements. Trino/delta automatically |
| 242 | + # converts the data values to the correct type on write, so we only need to handle |
| 243 | + # the column types in DDL. |
| 244 | + # - `timestamp(6)` for non-timezone-aware |
| 245 | + # - `timestamp(3) with time zone` for timezone-aware |
| 246 | + # https://trino.io/docs/current/connector/delta-lake.html#delta-lake-to-trino-type-mapping |
| 247 | + def _to_delta_ts( |
| 248 | + self, columns_to_types: t.Dict[str, exp.DataType] |
| 249 | + ) -> t.Dict[str, exp.DataType]: |
| 250 | + ts6 = exp.DataType.build("timestamp(6)") |
| 251 | + ts3_tz = exp.DataType.build("timestamp(3) with time zone") |
| 252 | + |
| 253 | + delta_columns_to_types = { |
| 254 | + k: ts6 if v.is_type(exp.DataType.Type.TIMESTAMP) else v |
| 255 | + for k, v in columns_to_types.items() |
| 256 | + } |
| 257 | + |
| 258 | + delta_columns_to_types = { |
| 259 | + k: ts3_tz if v.is_type(exp.DataType.Type.TIMESTAMPTZ) else v |
| 260 | + for k, v in delta_columns_to_types.items() |
| 261 | + } |
| 262 | + |
| 263 | + return delta_columns_to_types |
0 commit comments