Open jet10000 opened 4 years ago
I've encountered the same problem when using it with fastapi.
To me it looks like a pydantic problem: since we are not declaring the relation in the pydantic model, it gets excluded.
If I manage to find a solution, I'll post it.
I've seen that, but it doesn't work. When using fastapi, how's one supposed to do?
Taking from the example https://tortoise-orm.readthedocs.io/en/latest/examples/fastapi.html I have the models in a file together with the
User_Pydantic = pydantic_model_creator(Users, name="User")
UserIn_Pydantic = pydantic_model_creator(Users, name="UserIn", exclude_readonly=True)
pydantic delcarations.
In my endpoint, if I run await User_Pydantic.from_queryset_single(Users.get(id=user_id)prefetch_related("my_relation"))
, only returns the fields of the User model.
On the other hand, when I only use await Users.get(id=user_id)prefetch_related("my_relation")
, I can see a field representing the relation. Basically, it is lost when running User_Pydantic.from_queryset_single
.
You should call init_models
before get pydantic_model_creator
Isn't init_models
called by register_tortoise
when the connection is initialized?
I'm not understanding where to place it. Before the database initialization and the routers registration does not work.
Is there a complete example with fastapi and complex relations?
Yes, but it's called on app startup, your pydantic_model_creator
is after models module import, which is before of register_tortoise
I managed to make it work as you say.
Though to me it does not look great. I have to import within a function, which is not ideal in my opinion..
If there are better modules organizations, let me know.
In the meantime, thanks.
I have the same problem Here is my solution
class User(models.Model):
name = fields.CharField(max_length=100)
email = fields.CharField(max_length=50)
recipes: fields.ReverseRelation["Recipe"]
class Recipe(models.Model):
name = fields.CharField(max_length=100)
content = fields.TextField()
user = fields.ForeignKeyField("models.User")
User_Pydantic = pydantic_model_creator(Users, name="User")
UserIn_Pydantic = pydantic_model_creator(Users, name="UserIn", exclude_readonly=True)
Recipe_Pydantic_Base = pydantic_model_creator(Recipe, name='Recipe')
RecipeIn_Pydantic = pydantic_model_creator(Recipe, name="RecipeIn", exclude_readonly=True)
class Recipe_Pydantic(Recipe_Pydantic_Base):
user: User_Pydantic = Field(...)
@mao-shonen it doesn't look very clean to me (it's a personal view).
I ended up splitting orm
models and pydantic
models into two separate folders, namely "orm" and "schema". Then, at initialization phase, right after the Fastapi instance creation, the models are initialized and then the connection is performed.
I have re-read the document today I'm sorry, my previous answer was not good This is the correct one
https://tortoise-orm.readthedocs.io/en/latest/examples/pydantic.html#early-model-init
I have the same problem Here is my solution
class User(models.Model): name = fields.CharField(max_length=100) email = fields.CharField(max_length=50) recipes: fields.ReverseRelation["Recipe"] class Recipe(models.Model): name = fields.CharField(max_length=100) content = fields.TextField() user = fields.ForeignKeyField("models.User") User_Pydantic = pydantic_model_creator(Users, name="User") UserIn_Pydantic = pydantic_model_creator(Users, name="UserIn", exclude_readonly=True) Recipe_Pydantic_Base = pydantic_model_creator(Recipe, name='Recipe') RecipeIn_Pydantic = pydantic_model_creator(Recipe, name="RecipeIn", exclude_readonly=True) class Recipe_Pydantic(Recipe_Pydantic_Base): user: User_Pydantic = Field(...)
Hi! Where this "Field(...)" is imported from?
Thanks
@titogarrido
It is imported from Pydantic
See https://pydantic-docs.helpmanual.io/usage/types/#constrained-types