Python 没有 returns 实体关系的 Tortoise ORM(Pyndantic、FastAPI)
Tortoise ORM for Python no returns relations of entities (Pyndantic, FastAPI)
我正在使用 Tortoise ORM 作为异步 orm 库制作一个示例快速 Api 服务器,但我似乎无法 return 我定义的关系。这些是我的关系:
# 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)
表已正确创建。将关键字添加到类别时,数据库状态一切正常。问题是当我想查询类别并包含关键字时。我有这个代码:
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 我有以下内容:
category_orm debug at run-time
哪一种告诉我它们已加载。
然后当我不能使用 Pydantic 模型时,我有这个代码
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
调试这个,没有keywords
字段
category (pydantic) debug at run-time
查看函数from_tortoise_orm
的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.
但我的关系不是 returned。有没有人有类似的经历?
在初始化 Tortoise ORM 之前尝试生成 pydantic 模型时会出现此问题。如果您查看 basic pydantic 示例,您会发现所有 pydantic_model_creator
在 Tortoise.init
.
之后被调用
显而易见的解决方案是在 Tortoise 初始化之后创建 pydantic 模型,如下所示:
await Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]})
await Tortoise.generate_schemas()
Event_Pydantic = pydantic_model_creator(Event)
或者更方便的方法,通过Tortoise.init_models()
使用早期模型初始化。像这样:
from tortoise import Tortoise
Tortoise.init_models(["__main__"], "models")
Tournament_Pydantic = pydantic_model_creator(Tournament)
案例中,主要思想是将pydantic和db模型拆分成不同的模块,这样导入第一个不会导致提前创建第二个。并确保在创建 pydantic 模型之前调用 Tortoise.init_models()
。
可以找到更详细的示例说明 here。
我正在使用 Tortoise ORM 作为异步 orm 库制作一个示例快速 Api 服务器,但我似乎无法 return 我定义的关系。这些是我的关系:
# 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)
表已正确创建。将关键字添加到类别时,数据库状态一切正常。问题是当我想查询类别并包含关键字时。我有这个代码:
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 我有以下内容:
category_orm debug at run-time
哪一种告诉我它们已加载。 然后当我不能使用 Pydantic 模型时,我有这个代码
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
调试这个,没有keywords
字段
category (pydantic) debug at run-time
查看函数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.
但我的关系不是 returned。有没有人有类似的经历?
在初始化 Tortoise ORM 之前尝试生成 pydantic 模型时会出现此问题。如果您查看 basic pydantic 示例,您会发现所有 pydantic_model_creator
在 Tortoise.init
.
显而易见的解决方案是在 Tortoise 初始化之后创建 pydantic 模型,如下所示:
await Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]})
await Tortoise.generate_schemas()
Event_Pydantic = pydantic_model_creator(Event)
或者更方便的方法,通过Tortoise.init_models()
使用早期模型初始化。像这样:
from tortoise import Tortoise
Tortoise.init_models(["__main__"], "models")
Tournament_Pydantic = pydantic_model_creator(Tournament)
案例中,主要思想是将pydantic和db模型拆分成不同的模块,这样导入第一个不会导致提前创建第二个。并确保在创建 pydantic 模型之前调用 Tortoise.init_models()
。
可以找到更详细的示例说明 here。