-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
create_pydantic_model
returns models with wrong fields marked as null
#1132
Comments
@HakierGrzonzo I just have one question? Why adding a |
@sinisaos Using
Reason no.1 is common, annoying, but it is work-around-able. Reason no.2 stems from piccolo not really working with database-driven defaults (see #919). In conclusion, when generating the pydantic models, piccolo should treat the database as a source of truth for the |
@HakierGrzonzo Thank you for your time and detailed explanation. You are right that if we use def generate_uuid():
return str(uuid.uuid4())
class SomeThing(Table, db=DB):
uuid = columns.UUID(required=True, default=generate_uuid, null=False)
# uuid = columns.UUID(required=True, default=generate_uuid) # null is False by default I'm not sure if it's a good idea, but maybe we can force piccolo/piccolo/columns/base.py Line 504 in 7373a84
to this required=True if not null else required, Thanks again. |
This would fix the mentioned issue, thanks for responding. |
Sorry for the slow reply on this. I agree that the current behaviour is unintuitive. I remember people mentioning it in the past. I've opened a PR, where class Band(Table):
name = Varchar(null=True)
>>> create_pydantic_model(Band).model_fields['name'].annotation
Optional[str]
class Band(Table):
name = Varchar(null=False)
>>> create_pydantic_model(Band).model_fields['name'].annotation
str But class Band(Table):
name = Varchar(null=True, required=True)
>>> create_pydantic_model(Band).model_fields['name'].annotation
str If you use What do you both think? It's potentially a breaking change, but because the behaviour of |
When creating pydantic models with
create_pydantic_model
function, columns marked asnull
are not marked asnull
in the data. Instead the function uses therequired
property.How to recreate
Consider the following application:
The output returned is:
As we can see, the fields
name
andpet_name
are marked asstr | None
, despite having differentnull
options set.In contrast, the
age
field is marked as anint
, which may never beNone
, despite it being possiblynull
in the database.What causes this behavior:
piccolo/piccolo/utils/pydantic.py
Line 246 in 7373a84
In the above line, the type for the field is set as
T | None
based on therequired
property, instead of thenull
property.This generates plausible models for writing to the database, but not for reading data from the database (we get rogue nullable properties).
Why does this behavior need to be changed:
Let's consider a simple change to the example above:
We have an autogenerated
uuid
column, and we would like to create a model that describes a row in that table. We cannot markid
asrequired
as it might be generated by the database.The generated OpenAPI schema is:
This causes various OpenAPI client generators to generate the following type:
This makes it seem that the
id
might benull
, when it will never be null.How to fix this bug:
For my purposes, I just run this patch:
64629ca
This causes piccolo to generate the correct models for read operations.
For write purposes, I just use
all_optional
.The text was updated successfully, but these errors were encountered: