Create a Feast FeatureView from a dbt model. Args: model: The DbtModel to create a FeatureView from source: The DataSource for this FeatureView entity_columns: Entity column name(s) - single string or list of strings entities: Optiona
(
self,
model: DbtModel,
source: Any,
entity_columns: Union[str, List[str]],
entities: Optional[Union[Entity, List[Entity]]] = None,
timestamp_field: Optional[str] = None,
ttl_days: Optional[int] = None,
exclude_columns: Optional[List[str]] = None,
online: bool = True,
)
| 308 | ) |
| 309 | |
| 310 | def create_feature_view( |
| 311 | self, |
| 312 | model: DbtModel, |
| 313 | source: Any, |
| 314 | entity_columns: Union[str, List[str]], |
| 315 | entities: Optional[Union[Entity, List[Entity]]] = None, |
| 316 | timestamp_field: Optional[str] = None, |
| 317 | ttl_days: Optional[int] = None, |
| 318 | exclude_columns: Optional[List[str]] = None, |
| 319 | online: bool = True, |
| 320 | ) -> FeatureView: |
| 321 | """ |
| 322 | Create a Feast FeatureView from a dbt model. |
| 323 | |
| 324 | Args: |
| 325 | model: The DbtModel to create a FeatureView from |
| 326 | source: The DataSource for this FeatureView |
| 327 | entity_columns: Entity column name(s) - single string or list of strings |
| 328 | entities: Optional pre-created Entity or list of Entities |
| 329 | timestamp_field: Override the default timestamp field |
| 330 | ttl_days: Override the default TTL in days |
| 331 | exclude_columns: Additional columns to exclude from features |
| 332 | online: Whether to enable online serving |
| 333 | |
| 334 | Returns: |
| 335 | A Feast FeatureView |
| 336 | """ |
| 337 | # Normalize to lists |
| 338 | entity_cols: List[str] = ( |
| 339 | [entity_columns] |
| 340 | if isinstance(entity_columns, str) |
| 341 | else list(entity_columns) |
| 342 | ) |
| 343 | |
| 344 | entity_objs: List[Entity] = [] |
| 345 | if entities is not None: |
| 346 | entity_objs = [entities] if isinstance(entities, Entity) else list(entities) |
| 347 | |
| 348 | # Validate |
| 349 | if not entity_cols: |
| 350 | raise ValueError("At least one entity column must be specified") |
| 351 | |
| 352 | if entity_objs and len(entity_cols) != len(entity_objs): |
| 353 | raise ValueError( |
| 354 | f"Number of entity_columns ({len(entity_cols)}) must match " |
| 355 | f"number of entities ({len(entity_objs)})" |
| 356 | ) |
| 357 | |
| 358 | ts_field = timestamp_field or self.timestamp_field |
| 359 | ttl = timedelta(days=ttl_days if ttl_days is not None else self.ttl_days) |
| 360 | |
| 361 | # Columns to exclude from schema (timestamp + any explicitly excluded) |
| 362 | # Note: entity columns should NOT be excluded - FeatureView.__init__ |
| 363 | # expects entity columns to be in the schema and will extract them |
| 364 | excluded = {ts_field} |
| 365 | if exclude_columns: |
| 366 | excluded.update(exclude_columns) |
| 367 |