Tortoise-orm 使用(三) 一对一,一对多,多对多关系表及操作

2 篇文章 0 订阅
2 篇文章 1 订阅

基于官方的示例模型

from tortoise import Tortoise, fields, run_async
from tortoise.contrib.pydantic import pydantic_model_creator, pydantic_queryset_creator
from tortoise.models import Model


class Tournament(Model):
    id = fields.IntField(pk=True)
    name = fields.TextField()
    created_at = fields.DatetimeField(auto_now_add=True)

    events: fields.ReverseRelation["Event"]

    class Meta:
        ordering = ["name"]


class Event(Model):
    id = fields.IntField(pk=True)
    name = fields.TextField()
    created_at = fields.DatetimeField(auto_now_add=True)
    tournament: fields.ForeignKeyNullableRelation["Tournament"] = fields.ForeignKeyField(
        "models.Tournament", related_name="events", null=True
    )
    participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
        "models.Team", related_name="events", through="event_team"
    )
    address: fields.OneToOneNullableRelation["Address"]

    class Meta:
        ordering = ["name"]


class Address(Model):
    city = fields.CharField(max_length=64)
    street = fields.CharField(max_length=128)
    created_at = fields.DatetimeField(auto_now_add=True)

    event: fields.OneToOneRelation["Event"] = fields.OneToOneField(
        "models.Event", on_delete=fields.OnDelete.CASCADE, related_name="address", pk=True
    )

    class Meta:
        ordering = ["city"]


class Team(Model):
    id = fields.IntField(pk=True)
    name = fields.TextField()
    created_at = fields.DatetimeField(auto_now_add=True)

    events: fields.ManyToManyRelation["Event"]

    class Meta:
        ordering = ["name"]

1. 模型关联的定义

# 原始:

participants: fields.ManyToManyRelation[Team]

# 修改为:

participants: fields.ManyToManyRelation["Team"]

# 这样和其它模型定义关联保持一致,更容易理解

2. 关于示例模型的理解

官方示例很说明问题,其中涵盖了基本的表结构定义模式,已经双向引用的模式定义,具体使用方式参考官文就可以

Getting started - Tortoise ORM v0.20.0 Documentation

3. 使用ORM模块提供的Pydantic数据抽象模块

后续的例子会提供,从网上看到大多数教程大都自定义映射,繁琐且容易出错

4. 生成的数据表

通过创建的表和表结构,ORM为我们创建好了各种表和对应的关

模型测试

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

    Event_Pydantic = pydantic_model_creator(Event)
    Event_Pydantic_List = pydantic_queryset_creator(Event)
    Tournament_Pydantic = pydantic_model_creator(Tournament)
    Team_Pydantic = pydantic_model_creator(Team)

    Address_Pydantic = pydantic_model_creator(Address)

    tournament = await Tournament.create(name="New Tournament")
    tournament2 = await Tournament.create(name="Old Tournament")
    await Event.create(name="Empty")
    event = await Event.create(name="Test", tournament=tournament)
    event2 = await Event.create(name="TestLast", tournament=tournament)
    event3 = await Event.create(name="Test2", tournament=tournament2)
    await Address.create(city="Santa Monica", street="Ocean", event=event)
    await Address.create(city="Beijing", street="G6", event=event2)
    team1 = await Team.create(name="Onesies")
    team2 = await Team.create(name="T-Shirts")
    team3 = await Team.create(name="Alternates")
    await event.participants.add(team1, team2, team3)
    await event2.participants.add(team1, team2)
    await event3.participants.add(team1, team3)

    p = await Event_Pydantic.from_tortoise_orm(await Event.get(name="Test"))
    print("基于Event 'One Event:' \n", p.model_dump_json(indent=4))

    p = await Address_Pydantic.from_tortoise_orm(await Address.all().first())
    print("基于Address 'One Address:' \n", p.model_dump_json(indent=4))
    #
    p = await Tournament_Pydantic.from_tortoise_orm(await Tournament.get(name="New Tournament"))
    print("基于 Tournament 'One Tournament:'\n", p.model_dump_json(indent=4))
    #
    p = await Team_Pydantic.from_tortoise_orm(await Team.get(name="Onesies"))
    print("基于 Team 'One Team:' \n", p.model_dump_json(indent=4))
    #
    pl = await Event_Pydantic_List.from_queryset(Event.filter(address__event_id__isnull=True))
    print("All Events without addresses: \n", pl.model_dump_json(indent=4))


if __name__ == "__main__":
    run_async(run())

执行结果

基于Event 'One Event:' 
 {
    "id": 2,
    "name": "Test",
    "created_at": "2024-01-18T07:25:49.256352Z",
    "tournament": {
        "id": 1,
        "name": "New Tournament",
        "created_at": "2024-01-18T07:25:49.255311Z"
    },
    "participants": [
        {
            "id": 3,
            "name": "Alternates",
            "created_at": "2024-01-18T07:25:49.259313Z"
        },
        {
            "id": 1,
            "name": "Onesies",
            "created_at": "2024-01-18T07:25:49.258312Z"
        },
        {
            "id": 2,
            "name": "T-Shirts",
            "created_at": "2024-01-18T07:25:49.259313Z"
        }
    ],
    "address": {
        "city": "Santa Monica",
        "street": "Ocean",
        "created_at": "2024-01-18T07:25:49.258312Z",
        "event_id": 2
    }
}

基于Address 'One Address:' 
 {
    "city": "Beijing",
    "street": "G6",
    "created_at": "2024-01-18T07:25:49.258312Z",
    "event": {
        "id": 3,
        "name": "TestLast",
        "created_at": "2024-01-18T07:25:49.257311Z",
        "tournament": {
            "id": 1,
            "name": "New Tournament",
            "created_at": "2024-01-18T07:25:49.255311Z"
        },
        "participants": [
            {
                "id": 1,
                "name": "Onesies",
                "created_at": "2024-01-18T07:25:49.258312Z"
            },
            {
                "id": 2,
                "name": "T-Shirts",
                "created_at": "2024-01-18T07:25:49.259313Z"
            }
        ]
    },
    "event_id": 3
}

基于 Tournament 'One Tournament:'
 {
    "id": 1,
    "name": "New Tournament",
    "created_at": "2024-01-18T07:25:49.255311Z",
    "events": [
        {
            "id": 2,
            "name": "Test",
            "created_at": "2024-01-18T07:25:49.256352Z",
            "participants": [
                {
                    "id": 3,
                    "name": "Alternates",
                    "created_at": "2024-01-18T07:25:49.259313Z"
                },
                {
                    "id": 1,
                    "name": "Onesies",
                    "created_at": "2024-01-18T07:25:49.258312Z"
                },
                {
                    "id": 2,
                    "name": "T-Shirts",
                    "created_at": "2024-01-18T07:25:49.259313Z"
                }
            ],
            "address": {
                "city": "Santa Monica",
                "street": "Ocean",
                "created_at": "2024-01-18T07:25:49.258312Z",
                "event_id": 2
            }
        },
        {
            "id": 3,
            "name": "TestLast",
            "created_at": "2024-01-18T07:25:49.257311Z",
            "participants": [
                {
                    "id": 1,
                    "name": "Onesies",
                    "created_at": "2024-01-18T07:25:49.258312Z"
                },
                {
                    "id": 2,
                    "name": "T-Shirts",
                    "created_at": "2024-01-18T07:25:49.259313Z"
                }
            ],
            "address": {
                "city": "Beijing",
                "street": "G6",
                "created_at": "2024-01-18T07:25:49.258312Z",
                "event_id": 3
            }
        }
    ]
}

基于 Team 'One Team:' 
 {
    "id": 1,
    "name": "Onesies",
    "created_at": "2024-01-18T07:25:49.258312Z",
    "events": [
        {
            "id": 2,
            "name": "Test",
            "created_at": "2024-01-18T07:25:49.256352Z",
            "tournament": {
                "id": 1,
                "name": "New Tournament",
                "created_at": "2024-01-18T07:25:49.255311Z"
            },
            "address": {
                "city": "Santa Monica",
                "street": "Ocean",
                "created_at": "2024-01-18T07:25:49.258312Z",
                "event_id": 2
            }
        },
        {
            "id": 4,
            "name": "Test2",
            "created_at": "2024-01-18T07:25:49.257311Z",
            "tournament": {
                "id": 2,
                "name": "Old Tournament",
                "created_at": "2024-01-18T07:25:49.255311Z"
            },
            "address": null
        },
        {
            "id": 3,
            "name": "TestLast",
            "created_at": "2024-01-18T07:25:49.257311Z",
            "tournament": {
                "id": 1,
                "name": "New Tournament",
                "created_at": "2024-01-18T07:25:49.255311Z"
            },
            "address": {
                "city": "Beijing",
                "street": "G6",
                "created_at": "2024-01-18T07:25:49.258312Z",
                "event_id": 3
            }
        }
    ]
}

All Events without addresses: 
 [
    {
        "id": 1,
        "name": "Empty",
        "created_at": "2024-01-18T07:25:49.256352Z",
        "tournament": null,
        "participants": [],
        "address": null
    },
    {
        "id": 4,
        "name": "Test2",
        "created_at": "2024-01-18T07:25:49.257311Z",
        "tournament": {
            "id": 2,
            "name": "Old Tournament",
            "created_at": "2024-01-18T07:25:49.255311Z"
        },
        "participants": [
            {
                "id": 3,
                "name": "Alternates",
                "created_at": "2024-01-18T07:25:49.259313Z"
            },
            {
                "id": 1,
                "name": "Onesies",
                "created_at": "2024-01-18T07:25:49.258312Z"
            }
        ],
        "address": null
    }
]
 

  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值