Fastapi,tortoise-orm怎么实现数据库的迁移

 

最近在使用Fastapi编写代码时,结合tortoise-orm编写数据库的orm模型,实现关系型数据库的交互操作。Tortoise ORM 是一个受 Django 启发的易于使用的异步 ORM(对象关系映射器),其功能与Django的orm非常类似。

在编写完数据库模型以后,tortoise-orm会根据你的orm模型为你生成对应的数据库表,但是如果你后续想更改某个数据表的结构,比如添加,修改某些表字段,此时tortoise-orm无法为数据表进行你所需要的操作。我们可以借助第三方库Aerich进行数据库的迁移,下面示例演示在fastapi里面使用Aerich迁移数据库。
对应版本:
python==3.11
fastapi==0.110.0
tortoise-orm==0.20.0
aerich==0.7.2
mysql版本为5.8

0、我在apps下面的sql_models下面有个模型类

class User(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50, index=True, unique=True, description='用户名')
    password = fields.CharField(max_length=100, index=True, description='密码')

1、在fastapi中配置tortoise-orm所需要注册的配置信息

tortoise_config = {
    'connections': {
        'default': {
            'engine': 'tortoise.backends.mysql',
            # 数据库的基本配置信息
            'credentials': {
                'host': HOST,
                'port': PORT,
                'user': USER,
                'password': PASSWORD,
                'database': DB,
                'minsize': MINSIZE,
                'maxsize': MAXSIZE,
                'pool_recycle': POOL_RECYCLE * 3600,
            }
        },
    },
    'apps': {
        'models': {
        	# apps.sql_models为你编写的模型类的位置,比如这个为apps下面的sql_models里面,aerich.models保持默认即可
            'models': ['apps.sql_models', 'aerich.models', ], 
            'default_connection': 'default',
        }
    }
}

2、使用register_tortoise进行注册

def create_app():
    application = FastAPI()
    application.mount("/statics", StaticFiles(directory="statics"), name="statics")
    application.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
   register_tortoise(
        application, # fastapi实例
        config=tortoise_config, #数据库配置信息
        generate_schemas=False, # 立即生成模型,这里我们设置成False,因为我们使用aerich进行生成
        add_exception_handlers=True, #为DoesNotExist和IntegrityError添加一些自动异常处理程序,但是不建议在生产系统中使用,因为这可能会泄露数据。
    )
    return application

3、在fastapi的@app.on_event("startup")事件函数中进行数据库的迁移操作,这个函数用于定义当 FastAPI 应用启动时应该运行的函数或方法。这个事件处理函数通常用于执行应用启动时所需的初始化操作。

@app.on_event("startup")
async def create_db():
    command = Command(tortoise_config=tortoise_config)
    await command.init()
    # await command.migrate()
    await command.upgrade(run_in_transaction=True)

到了这一步基本配置信息已经完成了,现在万事俱备只欠东风了。接下来到项目的命令行终端输入一下两行命令。

aerich init -t app.tortoise_config
aerich init-db

即会在项目里面生成一个migrations/models/0_时间_init.py的初始迁移文件,有这个文件后只需重启fastapi服务就可生成对应的数据表。

9a629c7f4aba4185bf1fbbfe438e85eb.png

讲到这里,最基本的实现了,但是最重要的还是没有出现,就是如果更改了表结构怎么重新生成迁移文件呢?
比如说我需要在上面User模型中添加一个权限字段:

permission = fields.SmallIntField(index=True, description='权限')

在你添加完以后,需要把@app.on_event("startup")事件函数中await command.migrate()注释解开,重新启动服务即可,此时你会发现migrations/models文件夹下面新增了一个文件1_时间_update.py文件(注意生成新的迁移文件后,你需要再次把wait command.migrate()部分重新注释,避免误操作生成新的迁移文件),这时你会发现已经数据表结构已经更改成功了。

5f48cf0a036b4a1f80f6531b1c4a5c9d.png

 

 

 

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 FastAPITortoise-ORM、SQLAlchemy 和 peewee 进行 ORM 查询的示例。 ## Tortoise-ORM ```python from fastapi import FastAPI from tortoise import fields from tortoise.contrib.fastapi import register_tortoise, HTTPNotFoundError from tortoise.models import Model from tortoise import Tortoise class User(Model): id = fields.IntField(pk=True) name = fields.CharField(50) email = fields.CharField(50) class Meta: table = "users" app = FastAPI() @app.on_event("startup") async def startup(): await Tortoise.init( db_url="sqlite://db.sqlite3", modules={"models": ["main"]} ) await Tortoise.generate_schemas() @app.on_event("shutdown") async def shutdown(): await Tortoise.close_connections() @app.get("/users") async def get_users(): users = await User.all() return users @app.get("/users/{user_id}") async def get_user(user_id: int): user = await User.get_or_none(id=user_id) if user is None: raise HTTPNotFoundError return user register_tortoise( app, db_url="sqlite://db.sqlite3", modules={"models": ["main"]}, generate_schemas=True, add_exception_handlers=True ) ``` ## SQLAlchemy ```python from fastapi import FastAPI from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, index=True) name = Column(String(50)) email = Column(String(50)) engine = create_engine("sqlite:///db.sqlite3") SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) app = FastAPI() @app.get("/users") async def get_users(): db = SessionLocal() users = db.query(User).all() db.close() return users @app.get("/users/{user_id}") async def get_user(user_id: int): db = SessionLocal() user = db.query(User).filter(User.id == user_id).first() db.close() if user is None: raise HTTPNotFoundError return user ``` ## peewee ```python from fastapi import FastAPI from peewee import SqliteDatabase, Model, CharField, IntegerField from playhouse.shortcuts import model_to_dict db = SqliteDatabase("db.sqlite3") class User(Model): id = IntegerField(primary_key=True) name = CharField() email = CharField() class Meta: database = db table_name = "users" app = FastAPI() @app.on_event("startup") def startup(): db.connect() db.create_tables([User]) @app.on_event("shutdown") def shutdown(): db.close() @app.get("/users") async def get_users(): users = [model_to_dict(user) for user in User.select()] return users @app.get("/users/{user_id}") async def get_user(user_id: int): user = User.get_or_none(User.id == user_id) if user is None: raise HTTPNotFoundError return model_to_dict(user) ``` 注意:以上示例中的代码仅用于演示 ORM 查询的基本用法,并且没有进行错误处理。在实际应用中,你应该根据需要添加适当的错误处理和安全性检查。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值