Skip to content

Commit 99f4564

Browse files
committed
feat: pull field descriptions into db comments
1 parent a82c3fe commit 99f4564

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

sqlmodel/main.py

+32-2
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ def get_config(name: str) -> Any:
561561
# If it was passed by kwargs, ensure it's also set in config
562562
set_config_value(model=new_cls, parameter="table", value=config_table)
563563
for k, v in get_model_fields(new_cls).items():
564+
# convert FieldInfo definitions into sqlalchemy columns
564565
col = get_column_from_field(v)
565566
setattr(new_cls, k, col)
566567
# 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:
702703
raise ValueError(f"{type_} has no matching SQLAlchemy type")
703704

704705

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+
"""
706711
if IS_PYDANTIC_V2:
707712
field_info = field
708713
else:
709714
field_info = field.field_info
715+
710716
sa_column = getattr(field_info, "sa_column", Undefined)
711717
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+
712722
return sa_column
713-
sa_type = get_sqlalchemy_type(field)
723+
714724
primary_key = getattr(field_info, "primary_key", Undefined)
715725
if primary_key is Undefined:
716726
primary_key = False
727+
717728
index = getattr(field_info, "index", Undefined)
718729
if index is Undefined:
719730
index = False
731+
720732
nullable = not primary_key and is_field_noneable(field)
721733
# Override derived nullability if the nullable property is set explicitly
722734
# on the field
@@ -746,19 +758,37 @@ def get_column_from_field(field: Any) -> Column: # type: ignore
746758
"index": index,
747759
"unique": unique,
748760
}
761+
749762
sa_default = Undefined
750763
if field_info.default_factory:
751764
sa_default = field_info.default_factory
752765
elif field_info.default is not Undefined:
753766
sa_default = field_info.default
754767
if sa_default is not Undefined:
755768
kwargs["default"] = sa_default
769+
756770
sa_column_args = getattr(field_info, "sa_column_args", Undefined)
757771
if sa_column_args is not Undefined:
758772
args.extend(list(cast(Sequence[Any], sa_column_args)))
773+
759774
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+
760786
if sa_column_kwargs is not Undefined:
761787
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
762792
return Column(sa_type, *args, **kwargs) # type: ignore
763793

764794

0 commit comments

Comments
 (0)