aerich迁移tortoise-orm数据库教程

aerich迁移tortoise-orm数据库教程

目录

1.介绍

2.问题

3.tortoise-orm 自身函数迁移数据库

4.aerich命令迁移tortoise-orm数据库表

5.aerich代码迁移tortoise-orm数据库表

6. 注意事项(总结)


1.介绍

        tortoise-orm是异步orm,语法类似django-orm,非常简单方便;一般配合fastapi使用。

        tortoise-orm自身有generate_schemas函数用于数据库表创建

        但实际项目开发中使用较少,多用aerich来迁移model->数据库表

2.问题

        aerich 0.8.0和0.8.1 版本 cmd执行命令 存在问题,aerich init-db  upgrade等命令执行后 无法退出。

        原因:0.7.2以上版本,默认一直连接数据库(config里面有数据库连接路径),命令端无法退出连接,因此在代码程序中采用aerich Command执行命令,需要lifespan中Tortoise.close_connections

https://fastapi.tiangolo.com/zh/advanced/events/?h=lifespan#lifespan

        aerich 0.7.2版本 没有问题

3.tortoise-orm 自身函数迁移数据库

        建议看官网代码(点击查看),直接上代码,必须2个py文件(model单独1个py文件,main 1个文件),这样才不会报错

        Tortoise.init(db_url="sqlite://db.sqlite3", modules={"models": ["test"]})中 `models`可以改成任意名字,然后model表中外键、多对多需要改成对应名字.表名【models改成model,那么models.Clas需要改成model.Clas】,test为model表py模块(既可以是py文件也可是文件夹)

# test.py

from tortoise import fields, models, Tortoise
from enum import IntEnum

class AbstractModel(models.Model):
    id = fields.UUIDField(primary_key=True, unique=True, db_index=True)
    createdAt = fields.DatetimeField(auto_now_add=True, null=True)
    updatedAt = fields.DatetimeField(auto_now=True, null=True)
    class Meta:
        abstract = True

class Gender(IntEnum):
    MAN = 0
    WOMAN = 1

class Student(AbstractModel):
    name = fields.CharField(max_length=100, db_index=True, description="姓名")
    gender = fields.IntEnumField(Gender, description="性别")
    age = fields.IntField(description="年龄")
    clas = fields.ForeignKeyField("models.Clas", related_name="students", description="班级外键")


class Clas(AbstractModel):
    name = fields.CharField(max_length=200, db_index=True, description="班级名称")
    
# main.py

from tortoise import Tortoise, run_async
from test import Student, Clas

async def run():
    await Tortoise.init(db_url="sqlite://db.sqlite3", modules={"models": ["test"]})
    await Tortoise.generate_schemas()
    clas1 = await Clas.create(name="一年级一班1")
    stu = await Student.create(name="gyl", gender=1, age=30, clas=clas1)
    print(await Student.all().values())
    s = await Student.first().values()
    print(s['id'])
    print(s.keys())


if __name__=="__main__":
    run_async(run())

4.aerich命令迁移tortoise-orm数据库表

        使用版本为0.7.2,参考aerich官网(点击查看)命令,对于TORTOISE_ORM参数官网(点击查看)

        aerich命令

        aerich init -t config.TORTOISE_ORM     一般执行1次

        aerich init-db     一般执行1次

        aerich migrate     修改表就执行

        aerich upgrade (aerich downgrade)

TORTOISE_ORM配置参数

# 一般需要将 connections中的key 改成default 对应default_connection
'''
注意:TORTOISE_ORM中
        "apps": {
            "modelApp": {
                "models": ["models", "aerich.models"],  # models里面有__init__.py就不需要再.了
                "default_connection": "default" # 对应connections里面的
            }
        },
        
        `modelApp`(key) 是定义表外键、多对多时 “{app}.{table_name}”中的app, 若modelApp重命名, 则外键里面的app也改成对应的名字 clas = fields.ForeignKeyField("modelApp.Clas", related_name="students")
        `[]`里面的`models`是指的py模块路径(相对路径) 对于多级嵌套的的models文件夹 建议设置添加__init__.py导入所有表, 外键等就可以 modelApp."表名" 然后初始化创建表时 自动跟踪模块下面的所有table
'''

TORTOISE_ORM: dict = {
    "connections": {
        # SQLite configuration
        # "sqlite": {
        #     "engine": "tortoise.backends.sqlite",
        #     "credentials": {"file_path": f"{具体路径}/db.sqlite3"},  # Path to SQLite database file
        # },
        # MySQL/MariaDB configuration
        # Install with: tortoise-orm[asyncmy]
        # "mysql": {
        #     "engine": "tortoise.backends.mysql",
        #     "credentials": {
        #         "host": "localhost",  # Database host address
        #         "port": 3306,  # Database port
        #         "user": "yourusername",  # Database username
        #         "password": "yourpassword",  # Database password
        #         "database": "yourdatabase",  # Database name
        #     },
        # },
        # PostgreSQL configuration
        # Install with: tortoise-orm[asyncpg]
        # "postgres": {
        #     "engine": "tortoise.backends.asyncpg",
        #     "credentials": {
        #         "host": "localhost",  # Database host address
        #         "port": 5432,  # Database port
        #         "user": "yourusername",  # Database username
        #         "password": "yourpassword",  # Database password
        #         "database": "yourdatabase",  # Database name
        #     },
        # },
        # MSSQL/Oracle configuration
        # Install with: tortoise-orm[asyncodbc]
        # "oracle": {
        #     "engine": "tortoise.backends.asyncodbc",
        #     "credentials": {
        #         "host": "localhost",  # Database host address
        #         "port": 1433,  # Database port
        #         "user": "yourusername",  # Database username
        #         "password": "yourpassword",  # Database password
        #         "database": "yourdatabase",  # Database name
        #     },
        # },
        # SQLServer configuration
        # Install with: tortoise-orm[asyncodbc]
        # "sqlserver": {
        #     "engine": "tortoise.backends.asyncodbc",
        #     "credentials": {
        #         "host": "localhost",  # Database host address
        #         "port": 1433,  # Database port
        #         "user": "yourusername",  # Database username
        #         "password": "yourpassword",  # Database password
        #         "database": "yourdatabase",  # Database name
        #     },
        # },
    },
    'apps': {
        'models': {
            'models': ['models', 'aerich.models'], # []中的models为 表 模块(models.py或者models文件夹模块 需要有__init__.py导入表)
            # If no default_connection specified, defaults to 'default'
            'default_connection': 'default',
        }
    }
}

5.aerich代码迁移tortoise-orm数据库表

        版本使用0.8.1

        代码迁移,确保tortoise关闭连接,这样就不会出现代码执行后 无法退出的现象

from aerich import Command
from config import settings
from tortoise import Tortoise
async def init_db():
    # settings.TORTOISE_ORM参考第4节
    command = Command(tortoise_config=settings.TORTOISE_ORM)
    # try:
    #     await command.init_db(safe=True)
    # except FileExistsError:
    #     pass

    await command.init()  # 对应aerich init -t
    try:
        await command.init_db(safe=True)  # 对应aerich init-db
    except FileExistsError:
        pass
    try:
        await command.migrate()  # 对应aerich migrate
    except AttributeError:
        pass

    await command.upgrade(run_in_transaction=True)  # 对应aerich upgrade

async def lifespan():
    await init_db()
    await Tortoise.close_connections()  # 执行完成后 关闭Tortoise连接,即关闭数据库连接,像sqlite shm wal文件才会消失,不可直接删除,否则数据库没有数据

import asyncio
asyncio.run(lifespan())

6. 注意事项(总结)

        [1] 若采用aerich cmd端命令执行数据库创建、迁移,那么代码中推荐采用from tortoise.contrib.fastapi import register_tortoise,register_tortoise中generate_schemas调用的tortoise本身的函数迁移(不推荐生产使用,没有迁移记录);

        [2] 若采用aerich Command 代码程序,那么需要Fastapi中的lifespan,执行关闭数据库连接;

        [3] 目前个人采用[1]的aerich cmd命令端执行迁移,然后register_tortoise注册;[1]和[2]不要同时使用,后面可使用[2]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值