我孤身走在路上, 石子在雾中发亮,夜很安静,荒原面对太空,星星互诉衷肠
Fastapi使用Tortoise数据库引擎
Fastapi使用Tortoise数据库引擎

Fastapi使用Tortoise数据库引擎

什么是Fastapi

FastAPI是一个用于构建API的现代、快速(高性能)的web框架,基于Python 3.6类型提示,基于Starlette进行网络部分,基于Pydantic进行数据部分。

FastAPI的优势包括:

  1. 快速:非常高的性能,接近NodeJS和Go(由第三方测试)。
  2. 快速编码:提高开发速度约200%至300%。
  3. 少出错:减少约40%的人为错误(开发者)。
  4. 智能:优秀的编辑器支持。自动补全处处可见。少敲键,少犯错。
  5. 易用:被设计为易于使用和学习,减少阅读文档的时间。
  6. 简洁:减少代码重复。每个参数声明一次。多处复用。
  7. 健壮:可生产使用。以及自动交互式API文档。

可用的数据库引擎包括:

  1. SQLAlchemy:它是Python中最流行的ORM框架。使用SQLAlchemy,您可以通过Python代码来操作数据库,而不需要写SQL语句。优点是功能强大,社区活跃,支持异步操作。缺点是学习曲线较陡,配置复杂。
  2. Tortoise-ORM:它是一个易于使用的异步ORM框架,特别适合在FastAPI中使用。优点是异步支持良好,使用简单。缺点是功能相对SQLAlchemy较少,社区相对较小。
  3. MongoDB:如果您的应用需要非关系型数据库,MongoDB是一个很好的选择。优点是灵活,易于扩展,适合处理大量数据。缺点是需要额外学习NoSQL数据库的使用和管理。
  4. 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:

  1. 一对一关系查询:
# 假设我们想要获取login_name为'example'的用户的Profile
user = await User.filter(login_name='example').prefetch_related('profile').first()
  1. 一对多关系查询:
# 假设我们想要获取login_name为'example'的用户的所有Post
user = await User.filter(login_name='example').prefetch_related('posts').first()
  1. 多对多关系查询:
# 假设我们想要获取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数据引擎进行开发的基本示例

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

15 − 9 =