FastApi---Tortoise-ORM异步框架的使用

1. 配置数据库信息

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple -r .\req.txt

req.txt
pydantic-core==2.6.3
typing-extensions==4.7.1
python-multipart==0.0.5
aiomysql==0.2.0
pymysql==1.0.0
tortoise-orm==0.20.0

1.1 配置参数配置

settings.py
from fastapi import FastAPI
from tortoise.contrib.fastapi import HTTPNotFoundError, register_tortoise

app = FastAPI(title="Tortoise ORM FastAPI")


register_tortoise(
    # 这里是启动app的,之后会考虑和使用uvicorn启动的性能差别
    app,
    db_url="mysql://root:zxc123456@192.168.137.130:3306/fastapi",# 数据库信息
    modules={"models": ["models"]},# models列表路径
    # generate_schemas=True,# 如果数据库为空,则自动生成对应表单,生产环境不要开
    add_exception_handlers=True,# 生产环境不要开,会泄露调试信息
)


# settings.py
TORTOISE_ORM = {
    # 'connections': {
    #     'default': {
    #         # 'engine': 'tortoise.backends.asyncpg',  PostgreSQL
    #         'engine': 'tortoise.backends.mysql',  # MySQL or Mariadb
    #         'credentials': {
    #             'host': '192.168.137.130',
    #             'port': '3306',
    #             'user': 'root',
    #             'password': 'zxc123456',
    #             'database': 'fastapi',
    #             'minsize': 1,
    #             'maxsize': 5,
    #             'charset': 'utf8mb4',
    #             "echo": True
    #         }
    #     },
    # },
    "connections": {"default": "mysql://root:zxc123456@192.168.137.130:3306/fastapi"},
    'apps': {
        'models': {
            # models:models 找到对应自定义的model.py
            'models': ['models', "aerich.models"],  # aerich.models迁移模型
            'default_connection': 'default',
        }
    },
    'use_tz': False,
    'timezone': 'Asia/Shanghai'
}

1.2 创建数据模型

model.py
from tortoise import Model, fields


class User(Model):
    """数据库种的表"""
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=20)
    sex = fields.CharField(max_length=20, default="男")
    c_time = fields.DatetimeField(auto_now_add=True)
    u_time = fields.DatetimeField(auto_now=True)

1.3 ORM数据库生成

数据生成命令
 # 1. 打开命令行,切换到项目根目录 
cd tortoise_db
# 2. 初始化配置项
aerich init -t settings.TORTOISE_ORM

    #初始化完成后会在当前目录生成一个文件pyproject.toml和一个文件夹migrations
    #· pyproject.toml: 保存配置文件路径
    #. migrations:存放.sql迁移文件 
    
# 3. 初始化数据库,一般情况下只用一次
aerich init-db
    
    #· 如果TORTOISE_ORM配置文件中的models改了名,执行这条命令时需要增加--app参数,来指定你修改的名字。
    #· 在migrations的指定app目录下生成sql文件(如果model不为空时),并在数据库中生成表。

    
# 4. 更新模型并进行迁移
aerich migrate --name any_name
    
    #· 每次修改model后执行此命令,将在migrations文件夹下生成.sql迁移文件;
    #· --name参数为你的迁移文件添加备注,默认为update;
    #· 迁移文件名的格式为{version_num}{datetime}{any_name|update}.sql;
    #· 如果aerich识别到您正在重命名列,它会要求重命名{old_column}为{new_column} [True],您可以选择True
    #  重命名列而不删除列,或者选择False删除列然后创建,如果使用Mysql,只有8.0+支持重命名。
       
# 5. 更新最新修改到数据库
aerich upgrade    或aerich upgrade [xxx.sql]


# 6. 后续每次修改models文件内容(新增、删除或修改数据模型, 非models文件重命名),只需执行步骤4、5即可.

# 7. 其它操作
# 降级到指定版本
aerich downgrade -v 指定版本 -d 降级的同时删除迁移文件 --yes 确认删除,不再交互式输入

# 显示当前可以迁移的版本
aerich heads

# 显示迁移历史
aerich history

2. 项目使用

目录及结构

main.py
from models import User
from settings import app
from fastapi import Form
from tortoise import transactions


# 展示全部
@app.get("/")
async def get_user():
    user_all = await User.all()
    print("----------",user_all)
    print()
    return user_all


# 添加数据命令
@app.post("/add_data",)
async def add_data(name=Form(None), sex=Form(None)):
    print('------------------',name)
    await User(name=name, sex=sex).save()
    return dict(name=name, sex=sex)


# 单条数据查询
@app.api_route("/one_filter_data", methods=['post'])
async def like_data_filter(name=Form(None),):
    data = await User.filter(name=name).first()
    print(data)
    return {"data": data}


# 带有包含该字段值的数据。 任选其一
@app.post("/all_filter_data")
async def filter_all_data(name=Form(None), sex=None):
    # 加不加all()没什么区别
    data = await User.filter(name=name).all()
    data1 = await User.filter(sex=sex).all()
    data.append(data1)
    return {"data": data}


# 基于修改数据
@app.put("/put_filter_data")
@transactions.atomic()
async def put_filter_data(name=Form(None), id=Form(None), sex=Form(None)):
    await User.filter(id=id).update(name=name, sex=sex)
    return "修改成功"


# 删除数据
@app.delete("/delete_data")
async def del_data(id=Form(None)):
    await User.filter(id=id).delete()
    return "删除成功"

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="192.168.12.219", port=8088, )

3. ORM操作语法示例

必须在async异步函数中使

查询
 # 查询所有
stus = await Student.all()
# 过滤
stus = await Student.filter(name='张三')

# 模糊查询
stus = await Student.filter(name__contains='张')

# 查询值
stus = await Student.filter(name='张三').values('name', 'pwd')

# 获取单个对象
stu = await Student.get(name='张三')

# 多对多查询
courses = await Course.filter(students__name='张三').values('name')

# 一对多查询
stus = await Clas.filter(students__name='张三').values('name')
添加
 # 方式一
stu = Student(name='张三', pwd='123456', sno=1)
await stu.save()

# 方式二
stu = await Student.create(name='张三', pwd='123456', sno=1)

# 多对多关系
stu = await Student.get(name='张三')
course = await Course.get(name='语文')
await stu.courses.add(course)
修改
 # 方式一
stu = await Student.get(name='张三')
stu.name = '李四'
await stu.save()

# 方式二
await Student.filter(name='张三').update(name='李四')
删除
 # 方式一
stu = await Student.get(name='张三')
await stu.delete()

# 方式二
await Student.filter(name='张三').delete()

end..

 

posted @ 2023-09-06 18:38  王竹笙  阅读(1246)  评论(0编辑  收藏  举报