Python Tortoise ORM基础操作详解

1、测试环境准备

之前买过一台阿里云的开发机(99元/年),系统为Ubuntu2004,先安装一下mysql,供后面学习和调试tortoise库:

apt install mysql-client-core-8.0
apt-get install mysql-server

 

配置mysql root密码:

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '密码' PASSWORD EXPIRE NEVER; #更新一下用户的密码

mysql> UPDATE user SET host = '%' WHERE user = 'root'; #允许远程访问

创建数据库:

create database career;

 mysql安装完毕。

2、Tortoise介绍

Tortoise ORM 是一个为异步Python应用设计的ORM(对象关系映射)库,它允许开发者以面向对象的方式与关系型数据库进行交互,同时充分利用异步编程的优势来提高应用的性能,并且支持多种数据库:PostgreSQL、MySQL和SQLite等。

核心概念:

模型(Models):Tortoise ORM 使用Python类来定义数据库中的表结构。每个类代表一个数据库表,类的属性对应表中的列。

字段(Fields):在模型中定义字段,这些字段映射到数据库表的列。Tortoise ORM 提供了多种字段类型,如整型、字符串型、日期型等。

关系(Relations):Tortoise ORM 支持定义模型之间的关系,如一对一、一对多、多对多等。

异步操作:所有数据库操作都是异步的,使用async和await关键字来执行。
Tortoise ORM 特性:

【异步特性】:Tortoise ORM 的所有数据库操作都是异步的,这意味着它们可以在单线程中同时处理多个数据库请求,而不会阻塞彼此。提高了应用的并发性和性能。

【模型定义】:在Tortoise ORM 中,开发者使用Python类来定义数据库表结构。这些类中的属性对应于数据库表中的列,这使得数据库操作更加直观和易于理解。

【查询构建】:Tortoise ORM 提供了强大的查询构建功能,允许开发者构建复杂的查询条件,以检索所需的数据。这包括使用链式调用、比较运算符、逻辑运算符等。

【关系映射】:Tortoise ORM 支持定义模型之间的关系,如一对一、一对多、多对多等。这使得开发者可以轻松地处理复杂的数据关系,并在代码中以直观的方式表示它们。

【迁移和同步】:Tortoise ORM 还提供了数据库迁移工具,用于管理数据库模式的变更。这使得在应用开发过程中,可以轻松地添加、修改或删除表结构,而无需手动编写SQL语句。

3、连接数据库

安装依赖包:

pip install tortoise-orm
pip install aiomysql

初始化数据库:

async def init():

    await Tortoise.init(

        db_url="mysql://your_user_name:your_password@host:port/dbname",

        modules={"models": ["__main__"]},  # 当前模块下定义模型

    )

上面代码中,modules的设置,【__main__】代表模型定义在 __main__ 模块中,如果模型没有定义在当前main模块,填写具体路径即可,比如:

4、定义模型

模型,可以理解就是对应一张表,在这个模型里可以定义表的字段,表名等:

# 定义user模型

class User(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50, unique=True)
    age = fields.IntField()
    sex = fields.CharField(max_length=10)
    grade = fields.IntField()
    class Meta:
        table = "users"  # 数据库中表名
    def __str__(self):
        return f"User(id={self.id}, name='{self.name}', age={self.age})"

__str__ 方法:这是 Python 的一个特殊方法(魔术方法),当调用 str(obj) 或 print(obj) 时,会自动调用该方法来获取对象的可读字符串表示。

5、数据库的增、删、该、查

新增一条记录:

user = await User.create(name="Alice", age=30, sex = '女',grade= 4)
print("Inserted:", "name:",user.name, "age:",user.age, "sex:",user.sex, "grade:",user.grade)

create的返回值为User对象,数据为新增记录。

查询:

user_fetched = await User.filter(id=user.id).first()
print("Fetched:", "name:",user.name, "age:",user.age, "sex:",user.sex, "grade:",user.grade)

更新,有两种方式,第一种:

user_fetched = await User.filter(id=10).first()
user_fetched.age = 100
await user_fetched.save()
new_user = await User.filter(id=10).first()
print("Updated:", "name:",new_user.name, "age:",new_user.age, "sex:",new_user.sex, "grade:",new_user.grade)

 第二种,直接更新

cnt = await User.filter(id=10).update(age=3100)
print("cnt:", cnt)
new_doc = await User.filter(id=10).first()
print("Updated 2:", "name:",new_doc.name, "age:",new_doc.age, "sex:",new_doc.sex, "grade:",new_doc.grade)

删除: 

   # 🔹 删除
    dele = await User.filter(id=9).delete()
    print("Deleted cnt", dele)
    rec = await User.filter(id=9).first()
    if rec is not None:
        print("Not deleted")
    else:
        print("Deleted successfully")

6、一个小技巧:通过基类控制查询返回

如果我们想在查询时,某些字段固定不返回,或者个别字段的名称要做一下改变等二次处理的需求,我们可以设计一个基类,在这个基类里对数据做统一的处理:

class BaseModel(Model):
    # 
    _hidden_fields = ["id", "sex"] # 隐藏字段
    _field_map = {}  # 要返回的字段
    _filed_order = [] # 排序字段,
    def to_dict(self):
        result = {}
        fields_order = self._meta.fields or self._field_order
        for field in fields_order:
            if field in self._hidden_fields:
                continue
            value = getattr(self, field)
            if isinstance(value, datetime.datetime):
                value = value.strftime("%Y-%m-%d %H:%M:%S")
            s_key = self._field_map.get(field, field)
            result[s_key] = value
        return result

代码中_hidden_fields是不返回的字段,_field_map是可以返回的字段,_filed_order为排序字段,我们可以自由设置,在定义各个模型时,直接继承该基类即可。

 

效果如下:

 

以上就是tortoise的基本使用方法,希望对大家有所帮助。

全部的测试代码在这里,需要的可以自取:

https://github.com/liupengh3c/career/blob/main/python/tortoise/main.py

欢迎各位热爱技术的小伙伴们点个关注,聊聊跑步、聊聊技术、聊聊读书~~~。

往期推荐

我在百度的这10年~~

大同华严寺:受人民爱戴的耿市长还会回来吗?薄伽教藏的合掌漏齿菩萨你知道是谁吗?

云冈石窟:翻开这本距今1565年、与天地同久长的石头史书,感受北魏王朝雕刻艺术的巅峰之作。

历经沧桑的应县木塔,在风雨中已等你969年。

从北京到大同,走过600里,跨越1000年。

一个读写excel的简单程序(golang)

命令行参数的艺术:Python、Golang、C++技术实现

武汉抗疫英雄汪勇:平凡人的非凡之举。

李白:为何两次选择做了上门女婿?

纳兰性德-我是人间惆怅客,世间唯有『若』字,最难成真

RabbitMq:消费侧未限流导致的rabbitmq报错异常,消息不能正常消费。

一个异步架构设计:批量消费RabbitMQ,批量写入Elasticsearch(golang实现)

一个优秀的rabbitmq消费者(consumer)设计,可直接上线使用。

supervisor,你理应知道。

跑步的第六年,才真正了解运动的意义

借助tritonserver完成gpt2模型的本地私有化部署

一文揭秘:Golang+Elasticsearch轻松搭建AI时代的图片搜索服务

吭哧一天才搞定:elasticsearch向量检索需要的数据集以及768维向量生成

2025年,我要做个自我介绍

作者:棉花糖_码农夜读

物联沃分享整理
物联沃-IOTWORD物联网 » Python Tortoise ORM基础操作详解

发表回复