关于Python的sanic框架中listener的使用问题

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

@app.listener(‘before_server_start’) async def before_server_start(app, loop): # database config app.engine = create_engine(app.config[‘SQLALCHEMY_DATABASE_URI’], echo=app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’]) app.Base = declarative_base(bind=app.engine)

Session = sessionmaker(bind=app.engine)
app.db_session = Session()

app.Base.metadata.create_all()

这是我的一段代码,listener('before_server_start') 在服务启动前运行, 我把 sqlalchemy 所必须的几个对象和类变成 app ( Sanic 的对象)的属性后, 当我想要在 models 中想要类似这样定义的时候:

class User(app.Base)

却报错。

也就是说,模块加载的时间在 app.listener('before_server_start')运行之前。

不知道有用 Sanic+sqlalchemy 你们怎么做的?

文档给的一个 example。


关于Python的sanic框架中listener的使用问题

6 回复

有没有人知道怎么删帖,我想删除了,自己解决了。


在Sanic框架里,listener是用来在应用生命周期特定时刻执行代码的装饰器。主要就这几种:before_server_start, after_server_start, before_server_stop, after_server_stop。用起来很简单,直接在异步函数上加个装饰器就行。

比如,你想在服务器启动前初始化数据库连接池,可以这么写:

from sanic import Sanic

app = Sanic("MyApp")

@app.listener('before_server_start')
async def setup_db(app, loop):
    # 在这里初始化你的数据库连接池
    app.ctx.db_pool = await create_db_pool()
    print("数据库连接池已建立")

@app.listener('after_server_stop')
async def cleanup_db(app, loop):
    # 服务器关闭时清理资源
    await app.ctx.db_pool.close()
    print("数据库连接池已关闭")

关键点就两个:第一,listener函数必须是异步的(async def);第二,它至少接收apploop两个参数。app就是你的Sanic应用实例,方便你挂载一些全局对象(像上面例子里的app.ctx.db_pool);loop是当前的事件循环。

一个常见的坑是试图在before_server_start里访问还没完全初始化的app配置,这时候配置可能还没加载完。如果遇到这种依赖问题,可以考虑把初始化代码移到main函数里,或者用app.register_listener方法动态注册。

总之,listener就是Sanic给你留的几个钩子,用来在启动和关闭时插一些自定义逻辑,按需使用就行。

应该考虑是怎么解决的给后人一点提示

清空内容
转移节点至水
点击下沉

基本就可以了。

说个不相关的话题,sanic 并不好用,我自己的开源项目都想换 tornado 了。

最讨厌你这样的,不会的时候发帖问,自己有解决方案了就藏着掖着

回到顶部