sqlmesh.core.config.base
1from __future__ import annotations 2 3import typing as t 4from enum import Enum, auto 5 6from sqlmesh.utils.errors import ConfigError 7from sqlmesh.utils.pydantic import PydanticModel 8 9T = t.TypeVar("T", bound="BaseConfig") 10 11 12class UpdateStrategy(Enum): 13 """Supported strategies for adding new config to existing config""" 14 15 REPLACE = auto() # Replace with new value 16 EXTEND = auto() # Extend list to existing list 17 KEY_UPDATE = auto() # Update dict key value with new dict key value 18 KEY_EXTEND = auto() # Extend dict key value to existing dict key value 19 IMMUTABLE = auto() # Raise if a key tries to change this value 20 NESTED_UPDATE = auto() # Recursively updates the nested config 21 22 23def update_field( 24 old: t.Optional[t.Any], 25 new: t.Any, 26 update_strategy: t.Optional[UpdateStrategy] = None, 27) -> t.Any: 28 """ 29 Update config field with new config value 30 31 Args: 32 old: The existing config value 33 new: The new config value 34 update_strategy: The strategy to use when updating the field 35 36 37 The updated field 38 """ 39 if not old: 40 return new 41 42 update_strategy = update_strategy or UpdateStrategy.REPLACE 43 44 if update_strategy == UpdateStrategy.IMMUTABLE: 45 raise ConfigError(f"Cannot modify property: {old}.") 46 47 if update_strategy == UpdateStrategy.REPLACE: 48 return new 49 if update_strategy == UpdateStrategy.EXTEND: 50 if not isinstance(old, list) or not isinstance(new, list): 51 raise ConfigError("EXTEND behavior requires list field.") 52 53 return old + new 54 if update_strategy == UpdateStrategy.KEY_UPDATE: 55 if not isinstance(old, dict) or not isinstance(new, dict): 56 raise ConfigError("KEY_UPDATE behavior requires dictionary field.") 57 58 combined = old.copy() 59 combined.update(new) 60 return combined 61 if update_strategy == UpdateStrategy.KEY_EXTEND: 62 if not isinstance(old, dict) or not isinstance(new, dict): 63 raise ConfigError("KEY_EXTEND behavior requires dictionary field.") 64 65 combined = old.copy() 66 for key, value in new.items(): 67 if not isinstance(value, list): 68 raise ConfigError("KEY_EXTEND behavior requires list values in dictionary.") 69 70 old_value = combined.get(key) 71 if old_value: 72 if not isinstance(old_value, list): 73 raise ConfigError("KEY_EXTEND behavior requires list values in dictionary.") 74 75 combined[key] = old_value + value 76 else: 77 combined[key] = value 78 79 return combined 80 if update_strategy == UpdateStrategy.NESTED_UPDATE: 81 if not isinstance(old, BaseConfig): 82 raise ConfigError( 83 f"NESTED_UPDATE behavior requires a config object. {type(old)} was given instead." 84 ) 85 86 if type(new) != type(old): 87 raise ConfigError( 88 "NESTED_UPDATE behavior requires both values to have the same type. " 89 f"{type(old)} and {type(new)} were given instead." 90 ) 91 92 return old.update_with(new) 93 94 raise ConfigError(f"Unknown update strategy {update_strategy}.") 95 96 97class BaseConfig(PydanticModel): 98 """Base configuration functionality for configuration classes.""" 99 100 _FIELD_UPDATE_STRATEGY: t.ClassVar[t.Dict[str, UpdateStrategy]] = {} 101 102 def update_with(self: T, other: t.Union[t.Dict[str, t.Any], T]) -> T: 103 """Updates this instance's fields with the passed in config fields and returns a new instance. 104 105 Args: 106 other: Other configuration. 107 108 Returns: 109 New instance updated with the passed in config fields 110 """ 111 if isinstance(other, dict): 112 other = self.__class__(**other) 113 114 updated_fields = {} 115 116 for field in other.fields_set: 117 if field in self.all_field_infos(): 118 updated_fields[field] = update_field( 119 getattr(self, field), 120 getattr(other, field), 121 self._FIELD_UPDATE_STRATEGY.get(field), 122 ) 123 else: 124 updated_fields[field] = getattr(other, field) 125 126 # Assign each field to trigger assignment validators 127 updated = self.copy() 128 for field, value in updated_fields.items(): 129 setattr(updated, field, value) 130 131 return updated
class
UpdateStrategy(enum.Enum):
13class UpdateStrategy(Enum): 14 """Supported strategies for adding new config to existing config""" 15 16 REPLACE = auto() # Replace with new value 17 EXTEND = auto() # Extend list to existing list 18 KEY_UPDATE = auto() # Update dict key value with new dict key value 19 KEY_EXTEND = auto() # Extend dict key value to existing dict key value 20 IMMUTABLE = auto() # Raise if a key tries to change this value 21 NESTED_UPDATE = auto() # Recursively updates the nested config
Supported strategies for adding new config to existing config
REPLACE =
<UpdateStrategy.REPLACE: 1>
EXTEND =
<UpdateStrategy.EXTEND: 2>
KEY_UPDATE =
<UpdateStrategy.KEY_UPDATE: 3>
KEY_EXTEND =
<UpdateStrategy.KEY_EXTEND: 4>
IMMUTABLE =
<UpdateStrategy.IMMUTABLE: 5>
NESTED_UPDATE =
<UpdateStrategy.NESTED_UPDATE: 6>
Inherited Members
- enum.Enum
- name
- value
def
update_field( old: Union[Any, NoneType], new: Any, update_strategy: Union[sqlmesh.core.config.base.UpdateStrategy, NoneType] = None) -> Any:
24def update_field( 25 old: t.Optional[t.Any], 26 new: t.Any, 27 update_strategy: t.Optional[UpdateStrategy] = None, 28) -> t.Any: 29 """ 30 Update config field with new config value 31 32 Args: 33 old: The existing config value 34 new: The new config value 35 update_strategy: The strategy to use when updating the field 36 37 38 The updated field 39 """ 40 if not old: 41 return new 42 43 update_strategy = update_strategy or UpdateStrategy.REPLACE 44 45 if update_strategy == UpdateStrategy.IMMUTABLE: 46 raise ConfigError(f"Cannot modify property: {old}.") 47 48 if update_strategy == UpdateStrategy.REPLACE: 49 return new 50 if update_strategy == UpdateStrategy.EXTEND: 51 if not isinstance(old, list) or not isinstance(new, list): 52 raise ConfigError("EXTEND behavior requires list field.") 53 54 return old + new 55 if update_strategy == UpdateStrategy.KEY_UPDATE: 56 if not isinstance(old, dict) or not isinstance(new, dict): 57 raise ConfigError("KEY_UPDATE behavior requires dictionary field.") 58 59 combined = old.copy() 60 combined.update(new) 61 return combined 62 if update_strategy == UpdateStrategy.KEY_EXTEND: 63 if not isinstance(old, dict) or not isinstance(new, dict): 64 raise ConfigError("KEY_EXTEND behavior requires dictionary field.") 65 66 combined = old.copy() 67 for key, value in new.items(): 68 if not isinstance(value, list): 69 raise ConfigError("KEY_EXTEND behavior requires list values in dictionary.") 70 71 old_value = combined.get(key) 72 if old_value: 73 if not isinstance(old_value, list): 74 raise ConfigError("KEY_EXTEND behavior requires list values in dictionary.") 75 76 combined[key] = old_value + value 77 else: 78 combined[key] = value 79 80 return combined 81 if update_strategy == UpdateStrategy.NESTED_UPDATE: 82 if not isinstance(old, BaseConfig): 83 raise ConfigError( 84 f"NESTED_UPDATE behavior requires a config object. {type(old)} was given instead." 85 ) 86 87 if type(new) != type(old): 88 raise ConfigError( 89 "NESTED_UPDATE behavior requires both values to have the same type. " 90 f"{type(old)} and {type(new)} were given instead." 91 ) 92 93 return old.update_with(new) 94 95 raise ConfigError(f"Unknown update strategy {update_strategy}.")
Update config field with new config value
Arguments:
- old: The existing config value
- new: The new config value
- update_strategy: The strategy to use when updating the field
- The updated field
98class BaseConfig(PydanticModel): 99 """Base configuration functionality for configuration classes.""" 100 101 _FIELD_UPDATE_STRATEGY: t.ClassVar[t.Dict[str, UpdateStrategy]] = {} 102 103 def update_with(self: T, other: t.Union[t.Dict[str, t.Any], T]) -> T: 104 """Updates this instance's fields with the passed in config fields and returns a new instance. 105 106 Args: 107 other: Other configuration. 108 109 Returns: 110 New instance updated with the passed in config fields 111 """ 112 if isinstance(other, dict): 113 other = self.__class__(**other) 114 115 updated_fields = {} 116 117 for field in other.fields_set: 118 if field in self.all_field_infos(): 119 updated_fields[field] = update_field( 120 getattr(self, field), 121 getattr(other, field), 122 self._FIELD_UPDATE_STRATEGY.get(field), 123 ) 124 else: 125 updated_fields[field] = getattr(other, field) 126 127 # Assign each field to trigger assignment validators 128 updated = self.copy() 129 for field, value in updated_fields.items(): 130 setattr(updated, field, value) 131 132 return updated
Base configuration functionality for configuration classes.
def
update_with(self: ~T, other: Union[Dict[str, Any], ~T]) -> ~T:
103 def update_with(self: T, other: t.Union[t.Dict[str, t.Any], T]) -> T: 104 """Updates this instance's fields with the passed in config fields and returns a new instance. 105 106 Args: 107 other: Other configuration. 108 109 Returns: 110 New instance updated with the passed in config fields 111 """ 112 if isinstance(other, dict): 113 other = self.__class__(**other) 114 115 updated_fields = {} 116 117 for field in other.fields_set: 118 if field in self.all_field_infos(): 119 updated_fields[field] = update_field( 120 getattr(self, field), 121 getattr(other, field), 122 self._FIELD_UPDATE_STRATEGY.get(field), 123 ) 124 else: 125 updated_fields[field] = getattr(other, field) 126 127 # Assign each field to trigger assignment validators 128 updated = self.copy() 129 for field, value in updated_fields.items(): 130 setattr(updated, field, value) 131 132 return updated
Updates this instance's fields with the passed in config fields and returns a new instance.
Arguments:
- other: Other configuration.
Returns:
New instance updated with the passed in config fields
def
model_post_init(self: pydantic.main.BaseModel, _ModelMetaclass__context: Any) -> None:
102 def wrapped_model_post_init(self: BaseModel, __context: Any) -> None: 103 """We need to both initialize private attributes and call the user-defined model_post_init 104 method. 105 """ 106 init_private_attributes(self, __context) 107 original_model_post_init(self, __context)
Override this method to perform additional initialization after __init__
and model_construct
.
This is useful if you want to do some validation that requires the entire model to be initialized.
Inherited Members
- pydantic.main.BaseModel
- BaseModel
- model_extra
- model_fields_set
- model_construct
- model_copy
- model_dump
- model_dump_json
- model_json_schema
- model_parametrized_name
- model_rebuild
- model_validate
- model_validate_json
- model_validate_strings
- parse_file
- from_orm
- construct
- schema
- schema_json
- validate
- update_forward_refs