Tortoise ORM 是一个支持异步操作的 ORM 库,适用于现代 Python 应用程序,支持 PostgreSQL 和 MySQL 数据库。
1. Tortoise ORM 的基本概念
Tortoise ORM 提供了一种更直观的方式定义模型,同时也优化了异步操作的性能。
2. 安装 Tortoise ORM
首先需要安装 Tortoise ORM:
pip install tortoise-orm
3. 基础代码
使用 Tortoise ORM 编写代码:
from tortoise import Tortoise, fields, run_async
from tortoise.models import Model
from tortoise.contrib.pydantic import pydantic_model_creator
# 定义 User 模型
class User(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255)
settings = fields.JSONField() # 存储 JSON 配置
class Meta:
table = "users"
def __str__(self):
return self.name
# 初始化 Tortoise ORM 配置(异步)
async def init():
# 配置使用 PostgreSQL
await Tortoise.init(
db_url='postgres://user:password@localhost/database',
modules={'models': ['__main__']} # 指定模型所在的模块
)
# 生成表结构(如果表不存在)
await Tortoise.generate_schemas()
# 保存数据示例
async def save_user():
await init() # 初始化数据库连接
user = User(name="John Doe", settings={"theme": "dark", "language": "en"})
await user.save()
# 查询数据示例
async def get_users():
await init()
users = await User.all()
for user in users:
print(user)
# 最后运行示例
if __name__ == '__main__':
run_async(save_user())
run_async(get_users())
4. PostgreSQL 和 MySQL 的配置差异
Tortoise ORM 支持多种数据库,以下是 PostgreSQL 和 MySQL 的配置差异:
-
PostgreSQL 配置:
db_url = 'postgres://user:password@localhost/database'
-
MySQL 配置:
db_url = 'mysql://user:password@localhost/database'
两种数据库的配置主要差异在于 db_url
的前缀部分(postgres://
或 mysql://
),此外,Tortoise ORM 会自动检测数据库类型并使用相应的驱动程序。
5. 实用开发技巧
-
字段类型与可选参数: Tortoise ORM 提供丰富的字段类型,例如
IntField
、CharField
、JSONField
等,可以满足大多数数据存储需求。 -
异步操作: Tortoise ORM 支持异步操作,适合在高并发场景中使用。使用
await
关键字执行数据库操作。 -
模型操作:
-
创建:
user = User(name="John", settings={})
,然后调用await user.save()
。 -
查询:
users = await User.all()
获取所有用户。 -
更新:
user.name = "New Name"
后调用await user.save()
。 -
删除:
await user.delete()
。
-
-
生成表结构: Tortoise ORM 提供
generate_schemas()
方法,可以自动根据模型生成数据库表结构(如果表不存在)。 -
Pydantic 集成: Tortoise ORM 支持与 Pydantic 集成,可以轻松地将模型转换为 Pydantic 模型,便于数据验证和序列化:
User_Pydantic = pydantic_model_creator(User, name="User")
6. 复杂查询示例
以下是一些常用的复杂查询示例:
-
过滤查询:
users = await User.filter(name__contains="John")
-
排序:
users = await User.all().order_by('id')
-
分页:
users = await User.all().limit(10).offset(0)
-
关联查询: 如果有外键关系,可以使用
.prefetch_related()
方法进行关联查询:class Post(Model): author = fields.ForeignKeyField('models.User', related_name='posts') posts = await Post.all().prefetch_related('author')
-
原始 SQL 查询: 如果需要执行原始 SQL,可以使用
Tortoise.get_connection().execute_query()
:async def raw_query(): conn = Tortoise.get_connection("default") results = await conn.execute_query("SELECT * FROM users WHERE name LIKE %s", ["John%"]) print(results)
7. 数据库迁移
Tortoise ORM 提供了简单的迁移工具:
-
生成迁移文件:
tortoise shell
中运行Tortoise.init_and_generate_schemas()
。 -
应用迁移:手动应用迁移文件(Tortoise ORM 目前不支持自动迁移,但有计划支持)。
8. 性能优化技巧
-
批量操作:使用
bulk_create()
方法批量插入数据,减少数据库往返次数。 -
只查询需要的字段:使用
.values()
方法指定只查询需要的字段,减少数据传输量。 -
缓存:对于不经常变化的数据,可以使用缓存机制(如 Redis)减少数据库访问。
9. 安全注意事项
-
SQL 注入:Tortoise ORM 会自动转义特殊字符,避免 SQL 注入攻击。
-
敏感信息保护:对敏感字段(如密码)进行加密存储。
10. 常见问题解答
-
如何处理并发问题? Tortoise ORM 内置了事务支持,可以使用
async with in_transaction()
来处理并发场景:async with in_transaction() as connection: await User.create(name="John", settings={}) # 如果需要回滚,可以抛出异常
-
如何自定义字段类型? Tortoise ORM 支持自定义字段类型,可以通过继承
fields.Field
来实现。 -
如何处理 JSON 数据?
JSONField
支持存储和查询 JSON 数据,可以直接使用 Python 字典操作 JSON 数据:user = await User.get(id=1) print(user.settings["theme"]) # 直接访问 JSON 数据
11. 推荐工具
-
Tortoise Shell:使用
tortoise shell
命令进入交互式环境,方便调试。 -
Tortoise Admin:结合 Tortoise ORM 和 AdminLTE 框架,可以快速生成后台管理系统。
-
Aerich:Tortoise ORM 的迁移工具,支持生成和应用迁移。