run: python -m poetry install
- name: Install Pydantic v1
if: matrix.pydantic-version == 'pydantic-v1'
- run: pip install "pydantic>=1.10.0,<2.0.0"
+ run: pip install --upgrade "pydantic>=1.10.0,<2.0.0"
- name: Install Pydantic v2
if: matrix.pydantic-version == 'pydantic-v2'
- run: pip install "pydantic>=2.0.2,<3.0.0"
+ run: pip install --upgrade "pydantic>=2.0.2,<3.0.0"
- name: Lint
# Do not run on Python 3.7 as mypy behaves differently
if: matrix.python-version != '3.7' && matrix.pydantic-version == 'pydantic-v2'
def get_model_fields(model: InstanceOrType["SQLModel"]) -> Dict[str, "FieldInfo"]:
return model.model_fields
- def set_fields_set(
- new_object: InstanceOrType["SQLModel"], fields: Set["FieldInfo"]
- ) -> None:
- object.__setattr__(new_object, "__pydantic_fields_set__", fields)
+ def init_pydantic_private_attrs(new_object: InstanceOrType["SQLModel"]) -> None:
+ object.__setattr__(new_object, "__pydantic_fields_set__", set())
+ object.__setattr__(new_object, "__pydantic_extra__", None)
+ object.__setattr__(new_object, "__pydantic_private__", None)
def get_annotations(class_dict: Dict[str, Any]) -> Dict[str, Any]:
return class_dict.get("__annotations__", {})
def get_model_fields(model: InstanceOrType["SQLModel"]) -> Dict[str, "FieldInfo"]:
return model.__fields__ # type: ignore
- def set_fields_set(
- new_object: InstanceOrType["SQLModel"], fields: Set["FieldInfo"]
- ) -> None:
- object.__setattr__(new_object, "__fields_set__", fields)
+ def init_pydantic_private_attrs(new_object: InstanceOrType["SQLModel"]) -> None:
+ object.__setattr__(new_object, "__fields_set__", set())
def get_annotations(class_dict: Dict[str, Any]) -> Dict[str, Any]:
return resolve_annotations( # type: ignore[no-any-return]
get_model_fields,
get_relationship_to,
get_type_from_field,
+ init_pydantic_private_attrs,
is_field_noneable,
is_table_model_class,
post_init_field_info,
set_config_value,
- set_fields_set,
sqlmodel_init,
sqlmodel_validate,
)
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
new_object = super().__new__(cls)
- # SQLAlchemy doesn't call __init__ on the base class
+ # SQLAlchemy doesn't call __init__ on the base class when querying from DB
# Ref: https://docs.sqlalchemy.org/en/14/orm/constructors.html
# Set __fields_set__ here, that would have been set when calling __init__
# in the Pydantic model so that when SQLAlchemy sets attributes that are
# added (e.g. when querying from DB) to the __fields_set__, this already exists
- set_fields_set(new_object, set())
+ init_pydantic_private_attrs(new_object)
return new_object
def __init__(__pydantic_self__, **data: Any) -> None: