@@ -561,6 +561,7 @@ def get_config(name: str) -> Any:
561
561
# If it was passed by kwargs, ensure it's also set in config
562
562
set_config_value (model = new_cls , parameter = "table" , value = config_table )
563
563
for k , v in get_model_fields (new_cls ).items ():
564
+ # convert FieldInfo definitions into sqlalchemy columns
564
565
col = get_column_from_field (v )
565
566
setattr (new_cls , k , col )
566
567
# Set a config flag to tell FastAPI that this should be read with a field
@@ -702,21 +703,32 @@ def get_sqlalchemy_type(field: Any) -> Any:
702
703
raise ValueError (f"{ type_ } has no matching SQLAlchemy type" )
703
704
704
705
705
- def get_column_from_field (field : Any ) -> Column : # type: ignore
706
+ def get_column_from_field (field : PydanticFieldInfo | FieldInfo ) -> Column : # type: ignore
707
+ """
708
+ Takes a field definition, which can either come from the sqlmodel FieldInfo class or the pydantic variant of that class,
709
+ and converts it into a sqlalchemy Column object.
710
+ """
706
711
if IS_PYDANTIC_V2 :
707
712
field_info = field
708
713
else :
709
714
field_info = field .field_info
715
+
710
716
sa_column = getattr (field_info , "sa_column" , Undefined )
711
717
if isinstance (sa_column , Column ):
718
+ # if a db field comment is not already defined, and a description exists on the field, add it to the column definition
719
+ if not sa_column .comment and (field_comment := field_info .description ):
720
+ sa_column .comment = field_comment
721
+
712
722
return sa_column
713
- sa_type = get_sqlalchemy_type ( field )
723
+
714
724
primary_key = getattr (field_info , "primary_key" , Undefined )
715
725
if primary_key is Undefined :
716
726
primary_key = False
727
+
717
728
index = getattr (field_info , "index" , Undefined )
718
729
if index is Undefined :
719
730
index = False
731
+
720
732
nullable = not primary_key and is_field_noneable (field )
721
733
# Override derived nullability if the nullable property is set explicitly
722
734
# on the field
@@ -746,19 +758,37 @@ def get_column_from_field(field: Any) -> Column: # type: ignore
746
758
"index" : index ,
747
759
"unique" : unique ,
748
760
}
761
+
749
762
sa_default = Undefined
750
763
if field_info .default_factory :
751
764
sa_default = field_info .default_factory
752
765
elif field_info .default is not Undefined :
753
766
sa_default = field_info .default
754
767
if sa_default is not Undefined :
755
768
kwargs ["default" ] = sa_default
769
+
756
770
sa_column_args = getattr (field_info , "sa_column_args" , Undefined )
757
771
if sa_column_args is not Undefined :
758
772
args .extend (list (cast (Sequence [Any ], sa_column_args )))
773
+
759
774
sa_column_kwargs = getattr (field_info , "sa_column_kwargs" , Undefined )
775
+
776
+ if field_info .description :
777
+ if sa_column_kwargs is Undefined :
778
+ sa_column_kwargs = {}
779
+
780
+ assert isinstance (sa_column_kwargs , dict )
781
+
782
+ # only update comments if not already set
783
+ if "comment" not in sa_column_kwargs :
784
+ sa_column_kwargs ["comment" ] = field_info .description
785
+
760
786
if sa_column_kwargs is not Undefined :
761
787
kwargs .update (cast (Dict [Any , Any ], sa_column_kwargs ))
788
+
789
+ sa_type = get_sqlalchemy_type (field )
790
+
791
+ # if sa_column is not specified, then the column is constructed here
762
792
return Column (sa_type , * args , ** kwargs ) # type: ignore
763
793
764
794
0 commit comments