Skip to content

Commit 0e03bac

Browse files
earshinovEvgeny Arshinov
authored andcommitted
✨Add foreign_key_args and foreign_key_kwargs arguments to Field(...) to let the user define additional sqlalchemy.orm.ForeignKey attributes, such as ondelete and onupdate, for foreign keys defined in a base model.
1 parent 55abec9 commit 0e03bac

File tree

3 files changed

+464
-371
lines changed

3 files changed

+464
-371
lines changed

sqlmodel/main.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ def __init__(self, default: Any = Undefined, **kwargs: Any) -> None:
121121
sa_column = kwargs.pop("sa_column", Undefined)
122122
sa_column_args = kwargs.pop("sa_column_args", Undefined)
123123
sa_column_kwargs = kwargs.pop("sa_column_kwargs", Undefined)
124+
sa_foreign_key_args = kwargs.pop("sa_foreign_key_args", Undefined)
125+
sa_foreign_key_kwargs = kwargs.pop("sa_foreign_key_kwargs", Undefined)
124126
if sa_column is not Undefined:
125127
if sa_column_args is not Undefined:
126128
raise RuntimeError(
@@ -174,6 +176,8 @@ def __init__(self, default: Any = Undefined, **kwargs: Any) -> None:
174176
self.sa_column = sa_column
175177
self.sa_column_args = sa_column_args
176178
self.sa_column_kwargs = sa_column_kwargs
179+
self.sa_foreign_key_args = sa_foreign_key_args
180+
self.sa_foreign_key_kwargs = sa_foreign_key_kwargs
177181

178182

179183
class RelationshipInfo(Representation):
@@ -248,6 +252,8 @@ def Field(
248252
sa_type: Union[Type[Any], UndefinedType] = Undefined,
249253
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
250254
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
255+
sa_foreign_key_args: Union[Sequence[Any], UndefinedType] = Undefined,
256+
sa_foreign_key_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
251257
schema_extra: Optional[Dict[str, Any]] = None,
252258
) -> Any: ...
253259

@@ -384,6 +390,8 @@ def Field(
384390
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
385391
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
386392
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
393+
sa_foreign_key_args: Union[Sequence[Any], UndefinedType] = Undefined,
394+
sa_foreign_key_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
387395
schema_extra: Optional[Dict[str, Any]] = None,
388396
) -> Any:
389397
current_schema_extra = schema_extra or {}
@@ -422,6 +430,8 @@ def Field(
422430
sa_column=sa_column,
423431
sa_column_args=sa_column_args,
424432
sa_column_kwargs=sa_column_kwargs,
433+
sa_foreign_key_args=sa_foreign_key_args,
434+
sa_foreign_key_kwargs=sa_foreign_key_kwargs,
425435
**current_schema_extra,
426436
)
427437
post_init_field_info(field_info)
@@ -733,11 +743,19 @@ def get_column_from_field(field: Any) -> Column: # type: ignore
733743
if field_info.ondelete == "SET NULL" and not nullable:
734744
raise RuntimeError('ondelete="SET NULL" requires nullable=True')
735745
assert isinstance(foreign_key, str)
746+
fk_args = []
747+
fk_kwargs = {}
736748
ondelete = getattr(field_info, "ondelete", Undefined)
737-
if ondelete is Undefined:
738-
ondelete = None
739-
assert isinstance(ondelete, (str, type(None))) # for typing
740-
args.append(ForeignKey(foreign_key, ondelete=ondelete))
749+
if ondelete is not Undefined:
750+
assert isinstance(ondelete, (str, type(None)))
751+
fk_kwargs["ondelete"] = ondelete
752+
sa_foreign_key_args = getattr(field_info, "sa_foreign_key_args", Undefined)
753+
if sa_foreign_key_args is not Undefined:
754+
fk_args.extend(cast(Sequence[Any], sa_foreign_key_args))
755+
sa_foreign_key_kwargs = getattr(field_info, "sa_foreign_key_kwargs", Undefined)
756+
if sa_foreign_key_kwargs is not Undefined:
757+
fk_kwargs.update(cast(Dict[Any, Any], sa_foreign_key_kwargs))
758+
args.append(ForeignKey(foreign_key, *fk_args, **fk_kwargs))
741759
kwargs = {
742760
"primary_key": primary_key,
743761
"nullable": nullable,

0 commit comments

Comments
 (0)