Tortoise ORM 简单使用
文章目录
- Tortoise ORM
- 一、 简介
- 1、 ORM
- 2、 介绍
- 3、 简单使用
- 4、 环境配置
- 二、 基础配置
- 1、 数据库链接
- 2、 创建数据库
- 三、 模型
- 1、 创建
- 2、 多表关联
- 3、 字段
- 3.1 数据字段
- 3.2 关系字段
- 4、 查询
- 4.1 基础
- 4.2 Q 对象
- 4.3 F 表达式
- 五、 迁移
Tortoise ORM
一、 简介
1、 ORM
当您构建使用关系数据库的应用程序或服务时,有时您不能仅仅使用参数化查询甚至查询构建器就可以逃脱,您只是不断重复自己,为每个实体编写略有不同的代码。代码不知道数据之间的关系,因此您最终几乎是手动连接数据。访问数据库的方式也很容易出错,从而很容易发生 SQL 注入攻击。您的数据规则也是分布式的,增加了管理数据的复杂性,更糟糕的是,应用不一致。
ORM(对象关系映射器)旨在解决这些问题,通过集中您的数据模型和数据规则,确保您的数据得到安全管理(提供对 SQL 注入的免疫力)并跟踪关系,因此您不必。
2、 介绍
Tortoise ORM 是受 Django 启发的易于使用的asyncio
ORM (对象关系映射器) 。
Tortoise ORM 的构建类似于 Django ORM。它的设计中不仅使用表格,还使用关系数据。
与其他 Python ORM 相比,它也表现良好,与 Pony ORM 进行交易:
Django ORM 语法
SQLAlchemy 语法
官方文档地址:https://tortoise-orm.readthedocs.io/en/latest/index.html
3、 简单使用
创建模型:
from tortoise.models import Model
from tortoise import fieldsclass Tournament(Model):id = fields.IntField(pk=True)name = fields.TextField()
创建表,初始化数据库:
from tortoise import Tortoise, run_asyncasync def init():# Here we create a SQLite DB using file "db.sqlite3"# also specify the app name of "models"# which contain models from "app.models"await Tortoise.init(db_url='sqlite://db.sqlite3',modules={'models': ['app.models']})# Generate the schemaawait Tortoise.generate_schemas()# run_async is a helper function to run simple async Tortoise scripts.
run_async(init())
数据查询:
# Create instance by save
tournament = Tournament(name='New Tournament')
await tournament.save()# Or by .create()
await Tournament.create(name='Another Tournament')# Now search for a record
tour = await Tournament.filter(name__contains='Another').first()
print(tour.name)
4、 环境配置
pip install tortoise-orm# 安装数据库驱动
pip install tortoise-orm[asyncpg]
pip install tortoise-orm[aiomysql]
pip install tortoise-orm[asyncmy]
# 除此之外,还支持:aiosqlite
二、 基础配置
1、 数据库链接
Tortoise 目前支持以下数据库:
- SQLite
- PostgreSQL >= 9.4(使用
asyncpg
) - MySQL/MariaDB(使用
aiomysql
)
要使用,请确保已安装asyncpg
和/或aiomysql
Tortoise 支持以 URL 形式指定数据库配置:
语法:
DB_TYPE://USERNAME:PASSWORD@HOST:PORT/DB_NAME?PARAM1=value&PARAM2=value
支持的DB_TYPE
:
sqlite
:通常以 So if the is “/data/db.sqlite3” 那么字符串将是(注意三个 /)
sqlite://{DB_FILE}
如:
sqlite:///data/db.sqlite
postgres
:通常采用以下形式:
postgres://postgres:pass@db.host:5432/somedb
mysql
:通常采用以下形式:
mysql://myuser:mypass:pass@db.host:3306/somedb
更详细的可以进入官方文档查看:https://tortoise-orm.readthedocs.io/en/latest/databases.html
2、 创建数据库
from tortoise import Tortoise, run_asyncasync def init():# Here we create a SQLite DB using file "db.sqlite3"# also specify the app name of "models"# which contain models from "app.models"await Tortoise.init(db_url='sqlite://db.sqlite3',modules={'models': ['app.models']})# Generate the schemaawait Tortoise.generate_schemas() # safe:仅在表不存在时创建表run_async(init()) # 会自动进入上下文处理,在运行完成时,自动关闭数据库连接
三、 模型
1、 创建
from tortoise.models import Modelclass Tournament(Model):id = fields.IntField(pk=True)name = fields.TextField()created = fields.DatetimeField(auto_now_add=True)def __str__(self):return self.nameclass Event(Model):id = fields.IntField(pk=True)name = fields.TextField()tournament = fields.ForeignKeyField('models.Tournament', related_name='events')participants = fields.ManyToManyField('models.Team', related_name='events', through='event_team')modified = fields.DatetimeField(auto_now=True)prize = fields.DecimalField(max_digits=10, decimal_places=2, null=True)def __str__(self):return self.nameclass Team(Model):id = fields.IntField(pk=True)name = fields.TextField()class Meta:abstract = True # 设置为True表明这是一个抽象类table = "team" # 设置表名table_description = "" # 设置此项可为为当前模型创建的表生成注释消息unique_together = () # 指定unique_together为列集设置复合唯一索引,其为元组的元组(列表很好)indexes = () # 指定indexes为列集设置复合非唯一索引,它应该是元组的元组(列表很好)ordering = [] # 指定ordering为给定模型设置默认排序。.order_by(...)它应该可以迭代以与接收相同的方式格式化的字符串。如果查询是GROUP_BY使用默认排序的子句构建的,.annotate(...)则不应用。manager = tortoise.manager.Manager # 指定manager覆盖默认管理器。它应该是实例tortoise.manager.Manager或子类。
2、 多表关联
from tortoise.models import Model
from tortoise import fieldsclass Tournament(Model):id = fields.IntField(pk=True)name = fields.CharField(max_length=255)events: fields.ReverseRelation["Event"]def __str__(self):return self.nameclass Event(Model):id = fields.IntField(pk=True)name = fields.CharField(max_length=255)tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField("models.Tournament", related_name="events")participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField("models.Team", related_name="events", through="event_team")def __str__(self):return self.nameclass Team(Model):id = fields.IntField(pk=True)name = fields.CharField(max_length=255)events: fields.ManyToManyRelation[Event]def __str__(self):return self.name
3、 字段
更详细的信息可以查看官方文档:https://tortoise-orm.readthedocs.io/en/latest/fields.html
3.1 数据字段
Field(source_field = None , generated = False , pk = False , null = False , default = None , unique = False , index = False , description = None , model = None , validators = None , ** kwargs
参数:
- source_field (
Optional
[str
]) : 如果 DB 列名称需要是特定的而不是从字段名称中生成,则提供 source_field 名称。- generated (
bool
) : 该字段是否由数据库生成- pk (
bool
) :该字段是否为主键- null (
bool
) :主键是否可以为空- default (
Optional
[Any
]):该字段的默认值- unique (
bool
) :该字段的值是否唯一- index (
bool
):设置该字段是否为索引- description (
Optional
[str
]) :字段描述,也将出现在Tortoise.describe_model()
生成的 DDL 中并作为 DB 注释出现。- validators (
Optional
[List
[Union
[Validator
,Callable
]]]) :此字段的验证器
3.2 关系字段
ForeignKeyField( model_name , related_name = None , on_delete = 'CASCADE' , db_constraint = True , ** kwargs )
参数:
- model_name:关联模型的名称
{app}.{models}
- related_name:相关模型上的属性名称,用于反向解析外键
- on_delete:
field.CASCADE
:表示如果相关模型被删除,该模型应该被级联删除field.RESTRICT
:表示只要有外键指向,相关模型删除就会受到限制field.SET_NULL
:将字段重置为 NULL,以防相关模型被删除。仅当字段已设置时才能null=True
设置field.SET_DEFAULT
:将字段重置为default
值,以防相关模型被删除。只能设置是字段有一个default
集合- to_field:建立外键关系的相关模型上的属性名。如果未设置,则使用 pk
- db_constraint: 控制是否应在数据库中为此外键创建约束。默认值为 True,这几乎可以肯定是您想要的;将此设置为 False 可能对数据完整性非常不利
ManyToManyField(model_name, through=None, forward_key=None, backward_key='', related_name='', on_delete='CASCADE', db_constraint=True, **kwargs)
参数:
- through:通过中间表进行连接
- forward_key: 直通表上的正向查找键。默认值通常是安全的
- backward_key: 通表上的向后查找键。默认值通常是安全的
OneToOneField( model_name , related_name = None , on_delete = 'CASCADE' , db_constraint = True , ** kwargs )
这些参数在上面两个字段中全部都解释了,就不再进行解释
4、 查询
4.1 基础
模型本身有几种方法可以启动查询:
filter(*args, **kwargs)
:使用给定的过滤器创建 QuerySetexclude(*args, **kwargs)
:使用给定的排除过滤器创建 QuerySetall()
:创建不带过滤器的查询集first()
:创建仅限于一个对象的查询集并返回实例而不是列表annotate()
: 使用额外的函数/聚合对结果进行再过滤此方法返回
QuerySet
对象,允许进一步过滤和一些更复杂的操作
模型类也有这个方法来创建对象:
create(**kwargs)
:使用给定的 kwargs 创建对象get_or_create(defaults, **kwargs)
:获取给定 kwargs 的对象,如果未找到,则使用默认字典中的其他 kwargs 创建它
模型本身的实例也有这些方法:
save()
:更新实例,或者插入它,如果它以前从未保存过delete()
:从数据库中删除实例fetch_related(*args)
:获取与实例相关的对象。它可以获取 key关系、backward-key 关系。
values() # 返回queryset里面字段的值
values_list() # 返回queryset里面字段的值,同时,内部可以指定需要返回的字段的值events = await Event.filter(id__in=[1,2,3]).values('id', 'name', tournament_name='tournament__name') # 比如
使用
values()
或values_list()
生成更有效的查询
filter可以指定的对象:
not
in
:检查字段的值是否在传递列表中not_in
gte
:大于或等于传递的值gt
:大于传递值lte
:低于或等于传递的值lt
:低于通过值range
:介于和给定两个值之间isnull
:字段为空not_isnull
:字段不为空contains
:字段包含指定的子字符串icontains
:不区分大小写contains
startswith
:如果字段以值开头istartswith
:不区分大小写startswith
endswith
:如果字段以值结尾iendswith
:不区分大小写endswith
iexact
:不区分大小写等于search
:全文搜索
使用示例:
from tortoise.functions import Count, Trim, Lower, Upper, Coalesce# This query will fetch all tournaments with 10 or more events, and will
# populate filed `.events_count` on instances with corresponding value
await Tournament.annotate(events_count=Count('events')).filter(events_count__gte=10)
await Tournament.annotate(clean_name=Trim('name')).filter(clean_name='tournament')
await Tournament.annotate(name_upper=Upper('name')).filter(name_upper='TOURNAMENT')
await Tournament.annotate(name_lower=Lower('name')).filter(name_lower='tournament')
await Tournament.annotate(desc_clean=Coalesce('desc', '')).filter(desc_clean='')
同时,对于一对多和多对多,可以直接使用那个字段名进行数据的操作
4.2 Q 对象
Q 对象非常通用,一些示例用例:
- 创建 OR 过滤器
- 嵌套过滤器
- 倒置过滤器
- 结合以上任何一种来简单地编写复杂的多层过滤器
比如:
Q( * args , join_type = 'AND' , ** kwargs )
参数:
- join_type:连接类型,
OR\AND
- args (
Q
) :Q
要包装的内部表达式- kwargs (
Any
) :此 Q 对象应封装的过滤语句
found_events = await Event.filter(Q(Q(name='Event 1'), Q(name='Event 2'), join_type="OR") # Q(name='Event 1') | Q(name='Event 2')
)
4.3 F 表达式
F对象表示模型字段的值。它可以引用模型字段值并使用它们执行数据库操作,而无需将它们从数据库中拉出到 Python 内存中
from tortoise.expressions import F
await User.filter(id=1).update(balance = F('balance') - 10)
await User.filter(id=1).update(balance = F('balance') + F('award'), award = 0)# or use .save()
user = await User.get(id=1)
user.balance = F('balance') - 10
await user.save(update_fields=['balance'])
五、 迁移
我们使用Aerich进行迁移 :https://github.com/tortoise/aerich
安装:pip install aerich
aerich -hUsage: aerich [OPTIONS] COMMAND [ARGS]...Options:-c, --config TEXT Config file. [default: aerich.ini]--app TEXT Tortoise-ORM app name. [default: models]-n, --name TEXT Name of section in .ini file to use for aerich config.[default: aerich]-h, --help Show this message and exit.Commands:downgrade Downgrade to specified version.heads Show current available heads in migrate location.history List all migrate items.init Init config file and generate root migrate location.init-db Generate schema and generate app migrate location.migrate Generate migrate changes file.upgrade Upgrade to latest version.
用法:
您需要先将 aerich.models添加到您的Tortoise-ORM配置中
TORTOISE_ORM = {"connections": {"default": "mysql://root:123456@127.0.0.1:3306/test"},"apps": {"models": {"models": ["tests.models", "aerich.models"], "default_connection": "default",},},
}
初始化配置文件和设置:
aerich init -t tests.backends.mysql.TORTOISE_ORM
对数据库进行操作:
aerich init-db # 初始化数据库
aerich migrate --name drop_column # 更新并进行迁移
aerich upgrade # 升级数据库
aerich downgrade # 降级数据库到某个版本
aerich history # 显示迁移历史
aerich heads # 显示迁移的磁头
这里大部分是理论知识,例子可以自行到官方文档查看:https://tortoise-orm.readthedocs.io/en/latest/examples/
Tortoise ORM 简单使用相关推荐
- 数据库和ORMS:使用Tortoise ORM与数据库通信
文章目录 1. 安装环境 2. 创建数据库模型 3. 设置 `Tortoise` 引擎 4. create 5. 查询 6. 修改.删除 7. 添加关联 8. 用Aerich建立数据库迁移系统 lea ...
- python django ORM 简单的增删改查案例记录
在学习中摸索简单的ORM和模板层html的数据交互中的增删改查功能. 主要和网络教程不同的是我查询用的是fileter去对象,再在html中用for in给对象实例化,再获取对应属性的值,而b站的教程 ...
- django模型层FQ查询,only,defer关键字,orm简单事务
前言: Q查询-对对象的复杂查询 F查询–专门取对象中某列值的操作 Q查询 1.Q查询(django.db.models.Q)可以对关键字参数进行封装,从而更好的封装 from django.db.m ...
- 代码托管工具-Git/tortoise,develop与master的推送概念、日志找回以及小乌龟tortoise的简单使用
拿出来大家共勉,不足之处请指正. 很久之前的学习笔记了,一直存放在本地中 文章目录 develop 与 master的推送 把在develop完成的好文件推送到远程的master上 日志找回 找出项目 ...
- Web框架之Django_02基本操作(Django项目启动配置、数据库连接、orm、增删改查)
阅读目录 摘要: Django项目简单现实过程 pycharm连接数据库 Django之orm简单操作增删改查 一.新建Django项目.配置.设置: 新建Django项目:(为了熟悉Django操作 ...
- 利用python实现ORM
转载自:利用python实现ORM 做web开发的基本绕不过ORM,很多时候ORM可以大大减少开发工作量,那么ORM是怎样实现的呢?其实很简单,说穿了一文不值,本文先实现一个简单的ORM然后分析下现在 ...
- AgileEAS.NET之ORM访问器
上一篇文章AgileEAS.NET之数据关系映射ORM简单介绍了一下AgileEAS.NET平台中ORM对象的组织机构体系,但并没有对其所执行的数据存取操作介绍,在AgileEAS.NET中,我对OR ...
- ORM进阶之Hibernate 的三大对象
ORM进阶之 ORM简单介绍 ORM进阶之Hibernate 简单介绍及框架搭 ORM进阶之Hibernate 的三大对象 我们在上一篇博客中讲到了怎样搭建一个Hibernate框架, 提到Hiber ...
- python开发框架 代码生成_我的第一个python web开发框架(31)——定制ORM(七)...
几个复杂的ORM方式都已介绍完了,剩下一些常用的删除.获取记录数量.统计合计数.获取最大值.获取最小值等方法我就不一一详细介绍了,直接给出代码大家自行查看. 1 #!/usr/bin/env pyth ...
- python画圆填色橙色_基于TPC-C基准的Python ORM的性能测试详解
当开发与数据库需要在一起使用的应用程序时,对象关系映射器(ORM)通常用于Python编程中.Python ORM的示例是SQLAlchemy,Peewee,Pony-ORM和Django.选择ORM ...
最新文章
- 程序员崩溃的10个瞬间
- linux 指令tftp传输文件_tftp命令_Linux tftp 命令用法详解:在本机和tftp服务器之间使用TFTP协议传输文件...
- matlab常用工具箱的调用指令
- 2010年11月编程语言排行榜:手机里的代码
- 从零开始学习Hadoop--第2章 第一个MapReduce程序
- 神马是线程?PHP对其具体的应用?应用在哪里?
- rpm-tree源码分析一波
- RabbitMQ教程_4 Java 使用rabbitmq
- [索引汇总帖] 【eoeAndroid社区索引】Cocos2d-x部分汇总 [转贴]
- icmp数据包BE、LE解释
- No code “EPSG:4326“ from authority “EPSG“
- 解决h5兼容ios手机浏览器下载本地文件直接打开问题。
- 【记忆化搜索/数位DP】zznu2175(长度为n的含有ACM的字符串)
- 【不知出处】危险的迷宫 网络流 费用流
- 重磅丨数据+场景双重互联,有米广告完成程序化场景营销升级
- 虚幻4皮肤材质_虚幻引擎4.5版本预览说明
- 【计算机毕业设计】双月湾亲子高端酒店网站
- 墙裂推荐6个优质公众号
- 微信小程序授权登录和账号登录
- 南方cass怎么添加指北针_添加比例尺 指北针