Convert all fields to optional
First Check
- [X] I added a very descriptive title to this issue.
- [X] I used the GitHub search to find a similar issue and didn't find it.
- [X] I searched the SQLModel documentation, with the integrated search.
- [X] I already searched in Google "How to X in SQLModel" and didn't find any information.
- [X] I already read and followed all the tutorial in the docs and didn't find an answer.
- [X] I already checked if it is not related to SQLModel but to Pydantic.
- [X] I already checked if it is not related to SQLModel but to SQLAlchemy.
Commit to Help
- [X] I commit to help with one of those options 👆
Example Code
class HeroBase(SQLModel):
name: str
secret_name: str
age: Optional[int] = None
class HeroUpdate(HeroBase, all_optional=True):
pass
Description
Is it possible to add the ability to modify the fields of a base class to convert them to all optional with a parameter like the table=True but in this case all_optional=True? This would help eliminate the duplication when creating a class for making updates.
Wanted Solution
Set all base fields to Optional based on keyword argument.
Wanted Code
class HeroBase(SQLModel):
name: str
secret_name: str
age: Optional[int] = None
class HeroUpdate(HeroBase, all_optional=True):
pass
Alternatives
No response
Operating System
Linux, Windows
Operating System Details
No response
SQLModel Version
0.0.4
Python Version
3.8.5
Additional Context
No response
This is pydantic-related. You can make optional fields required in child classes, but you cannot make required fields optional.
Maybe the following resources will help you:
- https://github.com/samuelcolvin/pydantic/issues/1141#issuecomment-571247696
- https://stackoverflow.com/a/65907609/3778854
You can use a pattern like this instead:
class HeroBase(SQLModel):
# optional, aka nullable
name: Optional[str]
secret_name: Optional[str]
age: Optional[int]
class HeroCreate(HeroBase):
# all required
name: str
secret_name: str
age: int
class HeroUpdate(HeroBase):
pass
You can make optional fields required in child classes, but you cannot make required fields optional.
Perhaps this is not possible with class, however I think it is possible with type()?
In https://github.com/tiangolo/sqlmodel/issues/166 I link to a proposed method, make_updater_cls, that does this.
I am new to Pydantic + SQLModel so certainly welcome any feedback on this approach.
Edit: Upon closer consideration, I realize that my proposed method does not allow for making required fields optional on a class which inherits from the user-defined base model. Rather, a new class (which inherits directly from SQLModel) is created using the user-defined base model as reference. So the more general point about Python inheritance (child classes can't "optionalize" fields) is not disproved, but perhaps the practical application (how to generate an updater model from a base model) may still be possible.
I really find interesting the idea of creating a schema that inherits all fields from a SQLModel but make all of them Optional. Did you ever find a solution to this, @cisaacstern or @nickleman?
Also - it would be cool to have better control of which field should be optional and which not.
I was thinking about some kind of "decorator" mechanism to generate desired new class similar to this:
@Partial
class Hero(SQLModel):
id: int
@option
name: str
@option
secret_name: str
@remove
age: Optional[int] = None
Above code should generate 2 classes, first one with name Hero and the second one, like this:
class HeroPartial(SQLModel):
id: int
name: Optional[str]
secret_name: Optional[str]
@FilipeMarch apologies, I somehow missed your ping initially, and now a huge amount of time has passed. I have not thought about this issue in a while, but yes, the solution for a make_updater_cls method, proposed in my comment above, did work for me at the time.