Skip to content

Commit 9235285

Browse files
committed
refactor according to Yurii's suggestion
1 parent 16c21c1 commit 9235285

File tree

1 file changed

+21
-24
lines changed

1 file changed

+21
-24
lines changed

sqlmodel/main.py

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,17 @@ def Relationship(
476476
return relationship_info
477477

478478

479+
# Helper function to support Pydantic 2.12+ compatibility
480+
def _find_field_info(cls: type, field_name: str) -> Optional[FieldInfo]:
481+
for c in cls.__mro__:
482+
annotated = get_annotations(c.__dict__).get(field_name) # type: ignore[arg-type]
483+
if annotated:
484+
for meta in getattr(annotated, "__metadata__", ()):
485+
if isinstance(meta, FieldInfo):
486+
return meta
487+
return None
488+
489+
479490
@__dataclass_transform__(kw_only_default=True, field_descriptors=(Field, FieldInfo))
480491
class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):
481492
__sqlmodel_relationships__: Dict[str, RelationshipInfo]
@@ -562,31 +573,17 @@ def get_config(name: str) -> Any:
562573
# If it was passed by kwargs, ensure it's also set in config
563574
set_config_value(model=new_cls, parameter="table", value=config_table)
564575
for k, v in get_model_fields(new_cls).items():
565-
if not IS_PYDANTIC_V2:
566-
col = get_column_from_field(v)
567-
setattr(new_cls, k, col)
568-
continue
569-
570-
original_field = getattr(v, "_original_assignment", Undefined)
571-
# Get the original sqlmodel FieldInfo, pydantic >=v2.12 changes the model
572-
if isinstance(original_field, FieldInfo):
573-
field = original_field
576+
if PYDANTIC_MINOR_VERSION >= (2, 12):
577+
original_field = getattr(v, "_original_assignment", Undefined)
578+
# Get the original sqlmodel FieldInfo, pydantic >=v2.12 changes the model
579+
if isinstance(original_field, FieldInfo):
580+
field = original_field
581+
else:
582+
field = _find_field_info(new_cls, field_name=k) or v # type: ignore[assignment]
583+
field.annotation = v.annotation
584+
col = get_column_from_field(field)
574585
else:
575-
field = v # type: ignore[assignment]
576-
# Update the FieldInfo with the correct class from annotation.
577-
# This is required because pydantic overrides the field with its own
578-
# class and the reference for sqlmodel.FieldInfo is lost.
579-
for c in new_cls.__mro__:
580-
if annotated := get_annotations(c.__dict__).get(k): # type: ignore[arg-type]
581-
for meta in getattr(annotated, "__metadata__", ()):
582-
if isinstance(meta, FieldInfo):
583-
field = meta
584-
break
585-
break
586-
587-
field.annotation = v.annotation
588-
# Guarantee the field has the correct type
589-
col = get_column_from_field(field)
586+
col = get_column_from_field(v)
590587
setattr(new_cls, k, col)
591588
# Set a config flag to tell FastAPI that this should be read with a field
592589
# in orm_mode instead of preemptively converting it to a dict.

0 commit comments

Comments
 (0)