@@ -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 ))
480491class 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