Tortoise ORM for Python没有实体的返回关系(Pyndantic,FastAPI) [英] Tortoise ORM for Python no returns relations of entities (Pyndantic, FastAPI)

查看:230
本文介绍了Tortoise ORM for Python没有实体的返回关系(Pyndantic,FastAPI)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Tortoise ORM作为异步orm库制作了一个示例Fast Api服务器,但是似乎无法返回我定义的关系.这些是我的关系:

I was making a sample Fast Api server with Tortoise ORM as an asynchronous orm library, but I just cannot seem to return the relations I have defined. These are my relations:

# Category
from tortoise.fields.data import DatetimeField
from tortoise.models import Model
from tortoise.fields import UUIDField, CharField
from tortoise.fields.relational import ManyToManyField
from tortoise.contrib.pydantic import pydantic_model_creator


class Category(Model):
    id = UUIDField(pk=True)
    name = CharField(max_length=255)
    description = CharField(max_length=255)
    keywords = ManyToManyField(
        "models.Keyword", related_name="categories", through="category_keywords"
    )
    created_on = DatetimeField(auto_now_add=True)
    updated_on = DatetimeField(auto_now=True)



Category_dto = pydantic_model_creator(Category, name="Category", allow_cycles = True)

# Keyword
from models.expense import Expense
from models.category import Category
from tortoise.fields.data import DatetimeField
from tortoise.fields.relational import ManyToManyRelation
from tortoise.models import Model
from tortoise.fields import UUIDField, CharField
from tortoise.contrib.pydantic import pydantic_model_creator


class Keyword(Model):
    id = UUIDField(pk=True)
    name = CharField(max_length=255)
    description = CharField(max_length=255)
    categories: ManyToManyRelation[Category]
    expenses: ManyToManyRelation[Expense]
    created_on = DatetimeField(auto_now_add=True)
    updated_on = DatetimeField(auto_now=True)

    class Meta:
        table="keyword"


Keyword_dto = pydantic_model_creator(Keyword)

表已正确创建.将关键字添加到类别时,数据库状态很好.问题是当我想查询类别并包括关键字时.我有以下代码:

The tables have been created correctly. When adding keywords to categories the db state is all good. The problem is when i want to query the categories and include the keywords. I have this code for that:

class CategoryRepository():

    @staticmethod
    async def get_one(id: str) -> Category:
        category_orm = await Category.get_or_none(id=id).prefetch_related('keywords')
        if (category_orm is None):
            raise NotFoundHTTP('Category')
        return category_orm

在这里调试category_orm我有以下内容:

Debugging the category_orm here I have the following:

category_orm在运行时进行调试

哪种告诉我它们已加载.然后,当我无法创建Pydantic模型时,便有了此代码

Which kind of tells me that they are loaded. Then when i cant a Pydantic model I have this code

class CategoryUseCases():

    @staticmethod
    async def get_one(id: str) -> Category_dto:
        category_orm = await CategoryRepository.get_one(id)
        category = await Category_dto.from_tortoise_orm(category_orm)
        return category

并对其进行调试,没有关键字字段

and debugging this, there is no keywords field

在运行时进行类别(pydantic)调试

查看乌龟orm的源代码 from_tortoise_orm

Looking at the source code of tortoise orm for the function from_tortoise_orm

@classmethod
    async def from_tortoise_orm(cls, obj: "Model") -> "PydanticModel":
        """
        Returns a serializable pydantic model instance built from the provided model instance.

        .. note::

            This will prefetch all the relations automatically. It is probably what you want.

但是我的关系没有返回.任何人都有类似的经历吗?

But my relation is just not returned. Anyone have a similar experience ?

推荐答案

在初始化 Tortoise ORM之前,一种尝试生成pydantic模型的问题就会发生.如果您查看基本pydantic 例如,您会看到所有 pydantic_model_creator 都被称为之后 Tortoise.init .

The issue occurs when one try to generate pydantic models before Tortoise ORM is initialised. If you look at basic pydantic example you will see that all pydantic_model_creator are called after Tortoise.init.

显而易见的解决方案是在Tortoise初始化后创建pydantic模型,如下所示:

The obvious solution is to create pydantic models after Tortoise initialisation, like so:


await Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]})
await Tortoise.generate_schemas()

Event_Pydantic = pydantic_model_creator(Event)

或更方便的方法是,通过 Tortoise.init_models()使用早期模型init .像这样:

Or a more convenient way, use early model init by means of Tortoise.init_models(). Like so:


from tortoise import Tortoise

Tortoise.init_models(["__main__"], "models")
Tournament_Pydantic = pydantic_model_creator(Tournament)

在这种情况下,主要思想是将pydantic模型和db模型分为不同的模块,以便导入第一个模块不会导致提前创建第二个模块.并确保在创建pydantic模型之前调用 Tortoise.init_models().

In the case, the main idea is to split pydantic and db models into different modules, so that importing the first does not lead to the creation of the second ahead of time. And ensure calling Tortoise.init_models() before creating pydantic models.

有关示例的更详细说明,请参见此处.

A more detailed description with examples can be found here.

这篇关于Tortoise ORM for Python没有实体的返回关系(Pyndantic,FastAPI)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆