什么是Fastapi
FastAPI是一个用于构建API的现代、快速(高性能)的web框架,基于Python 3.6类型提示,基于Starlette进行网络部分,基于Pydantic进行数据部分。
FastAPI的优势包括:
- 快速:非常高的性能,接近NodeJS和Go(由第三方测试)。
- 快速编码:提高开发速度约200%至300%。
- 少出错:减少约40%的人为错误(开发者)。
- 智能:优秀的编辑器支持。自动补全处处可见。少敲键,少犯错。
- 易用:被设计为易于使用和学习,减少阅读文档的时间。
- 简洁:减少代码重复。每个参数声明一次。多处复用。
- 健壮:可生产使用。以及自动交互式API文档。
可用的数据库引擎包括:
- SQLAlchemy:它是Python中最流行的ORM框架。使用SQLAlchemy,您可以通过Python代码来操作数据库,而不需要写SQL语句。优点是功能强大,社区活跃,支持异步操作。缺点是学习曲线较陡,配置复杂。
- Tortoise-ORM:它是一个易于使用的异步ORM框架,特别适合在FastAPI中使用。优点是异步支持良好,使用简单。缺点是功能相对SQLAlchemy较少,社区相对较小。
- MongoDB:如果您的应用需要非关系型数据库,MongoDB是一个很好的选择。优点是灵活,易于扩展,适合处理大量数据。缺点是需要额外学习NoSQL数据库的使用和管理。
- PostgreSQL:如果你需要一个强大的关系型数据库,PostgreSQL是一个不错的选择。它支持复杂的查询和事务,适合需要高度一致性的应用。优点是功能强大,性能优秀。缺点是相比其他数据库,可能需要更多的资源来运行和管理。
以上都是一些常见的选择,由于Fastapi是异步框架,在高并发的情况下首选Tortoise-ORM,因为这个数据库引擎也是异步的,下面是这个引擎的一些基础配置:
自定义你的db_config文件,我的信息都是从配置文件中读取的,没有从变量中读取,你也可以写死,但是不推荐,真正开发没人这么干吧,内容如下:
# -*- coding: utf-8 -*-
"""
Author : Taering
Project : Demo
Description :
2022/9/15
"""
from util.config.getconfig import Conf
get_properties = Conf()
TORTOISE_ORM = {
'connections': {
'default': {
'engine': 'tortoise.backends.mysql', # MySQL or Mariadb
'credentials': {
'host': get_properties.get_mysql_host, # 数据库的地址
'port': get_properties.get_mysql_port, # 数据库端口
'user': get_properties.get_mysql_user, # 数据库用户
'password': get_properties.get_mysql_passwd, # 数据库密码
'database': get_properties.get_mysql_database, # 使用的数据库
'minsize': 1,
'maxsize': 20,
'charset': 'utf8mb4',
"echo": True # 开启后会在控制台打印出sql语句,开发环境还是不错的DEBUG选项
}
},
},
'apps': {
'models': {
'models': ['你的MODEL的位置,例如model.py,反正路径写对就行了,后面的不要动', "aerich.models"],
'default_connection': 'default',
}
},
'use_tz': False,
'timezone': 'Asia/Shanghai'
}
主文件中导入你的配置
from 你的初始化文件的位置 import TORTOISE_ORM
# 初始化MYSQL
register_tortoise(
app,
config=TORTOISE_ORM,
generate_schemas=True, # 如果数据库为空,则自动生成对应表单,生产环境不要开
add_exception_handlers=True, # 生产环境不要开,会泄露调试信息
)
创建MODEL简单的案例:
from tortoise.models import Model
from tortoise import fields
class User(Model):
id = fields.IntField(pk=True) # 主键字段
login_name = fields.CharField(max_length=50) # 登录名,字符串类型,最大长度50
name = fields.CharField(max_length=50) # 名字,字符串类型,最大长度50
gender = fields.CharField(max_length=10) # 性别,字符串类型,最大长度10
class Meta:
table = "user" # 指定数据库中的表名
在Tortoise ORM中,你可以通过在模型字段中设置相应的选项来实现索引及关系建立。以下是一些例子:
为某个字段建立索引:
class User(Model):
login_name = fields.CharField(max_length=50, index=True) # 为登录名字段建立索引
为某个字段建立唯一索引:
class User(Model):
login_name = fields.CharField(max_length=50, unique=True) # 为登录名字段建立唯一索引
为某两个字段建立联合索引
class User(Model):
login_name = fields.CharField(max_length=50)
email = fields.CharField(max_length=100)
class Meta:
indexes = [("login_name", "email")] # 为登录名和邮箱字段建立关联索引
一对一关系建立
class User(Model):
profile = fields.OneToOneField('models.Profile', related_name='user') # 一对一关系,User和Profile
class Profile(Model):
pass # Profile的其他字段
一对多关系建立
class User(Model):
posts = fields.ReverseRelation['Post'] # 一对多关系,User和Post
class Post(Model):
user = fields.ForeignKeyField('models.User', related_name='posts') # Post的其他字段
多对多关系建立
class User(Model):
groups = fields.ManyToManyField('models.Group', related_name='users') # 多对多关系,User和Group
class Group(Model):
pass # Group的其他字段
查询语句相关
Tortoise ORM支持在一条语句中直接查询关联的数据。下面是一些DEMO:
- 一对一关系查询:
# 假设我们想要获取login_name为'example'的用户的Profile
user = await User.filter(login_name='example').prefetch_related('profile').first()
- 一对多关系查询:
# 假设我们想要获取login_name为'example'的用户的所有Post
user = await User.filter(login_name='example').prefetch_related('posts').first()
- 多对多关系查询:
# 假设我们想要获取login_name为'example'的用户的所有Group
user = await User.filter(login_name='example').prefetch_related('groups').first()
在这些DEMO中,我们使用了prefetch_related方法来预先加载关联的数据。这样,当我们访问这些关联的数据时,Tortoise ORM不需要再去数据库中查询,而是直接返回已经加载的数据,这可以提高查询的效率。
外键的建立:
在Tortoise ORM中,我们可以使用ForeignKeyField来定义外键。以下是一个例子:
from tortoise.models import Model
from tortoise import fields
class Team(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=100)
class Player(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=100)
team = fields.ForeignKeyField('models.Team', related_name='players')
在这个例子中,我们定义了两个模型:Team和Player。每个Player都属于一个Team,所以在Player模型中定义了一个外键字段team,它引用了Team模型。ForeignKeyField的第一个参数是引用的模型的字符串表示,第二个参数related_name是用来在被引用的模型中反向引用这个模型的名称。在这个DEMO中,我们可以通过team.players来获取一个Team的所有Player。
Aerich的介绍
这个插件常规的方式网上有很多教程都已经说明了,这里就不再说了,只是要提一下,有时候某些项目比较简单,你们公司的DBA已经把库建好了,那么我们就需要将数据库转换成model模型类,这样的话就免去了我们从头再建MODEL,虽然可以,但是有一些限制,比如有外键的就不行
初始化数据库
aerich init-db
映射所有的表并输出到控制台
aerich --app models inspectdb
指定一个表进行映射
aerich inspectdb -t user
映射所有表并将内容输出到文件当中(通常不会将映射内容直接输出到控制台)
aerich --app models inspectdb > models.py
以上是一些关于Fastpi配合tortoise数据引擎进行开发的基本示例