flask是Python众多web框架中的一个,相比于django,flask是一个micro web framework,学习成本低,易上手。同时flask extension设计得非常方便,flask生态圈比较完善。sqlalchemy也是老牌的python ORM框架,其内置的events注册机制,可以灵活实现各种功能。flask-sqlalchemy则利用了flask和sqlalchemy易于扩展的优点,在flask中对sqlalchemy做了封装,为flask使用者节省了不少时间,少写代码,简化逻辑。本文对flask-sqlalchemy进行简单介绍。
from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy.pool import Pool
@event.listens_for(Pool, "checkout")
def ping_connection(dbapi_connection, connectidon_record, connection_proxy):
cursor = dbapi_connection.cursor()
try:
cursor.execute("SELECT 1")
except:
# optional - dispose the whole pool
# instead of invalidating one at a time
# connection_proxy._pool.dispose()
# raise DisconnectionError - pool will try
# connecting again up to three times before raising.
raise exc.DisconnectionError()
cursor.close()
connection_record:the _ConnectionRecord managing the DBAPI connection。
PoolEvents中有以下这些事件:
checkin():当connection被返回pool时 Note that the connection may be closed, and may be None if the connection has been invalidated. checkin will not be called for detached connections. (They do not return to the pool.)
invalidate():This event is called any time the _ConnectionRecord.invalidate() method is invoked, either from API usage or via “auto-invalidation”. The event occurs before a final attempt to call .close() on the connection occurs
前言
flask是Python众多web框架中的一个,相比于django,flask是一个micro web framework,学习成本低,易上手。同时flask extension设计得非常方便,flask生态圈比较完善。sqlalchemy也是老牌的python ORM框架,其内置的events注册机制,可以灵活实现各种功能。flask-sqlalchemy则利用了flask和sqlalchemy易于扩展的优点,在flask中对sqlalchemy做了封装,为flask使用者节省了不少时间,少写代码,简化逻辑。本文对flask-sqlalchemy进行简单介绍。
flask-sqlalchemy在sqlalchemy基础上封装了什么
db.query扩展了sqlalchemy.orm.query.Query,增加了get_or_404、first_or_404和paginate函数
flask-sqlalchemy中的SQLAlchemy类,附加了sqlalchemy和sqlalchemy.orm中的所有属性/- 函数,所有比如db.Column。并把db.relatetionship/relation等属性设置为sqlalchemy的relati- on的扩展。【见flask-sqlalchemy文件init.py中的_include_sqlalchemy函数】
flask-sqlalchemy中的db.session其实就是sqlalchemy中的scope_session,适配flask的reque- st/response server的特点
flask-sqlalchemy中把sqlalchemy的session与flask的signal注册在一起【flask - signal主要是connection和send,实现为signal register callback函数】
flask-sqlalchemy其实就是使用flask extension实现的一个扩展
了解一下sqlalchemy的event注册方式
先看一段代码,这段代码是在生产环境中使用的,目的是保证在sqlalchemy在切换数据库后pool中connection依然可用(如果不加,访问已断开的connection会出错)
这段代码的意思就是,每次都在connection从pool中取出后,通过一个“SELECT 1”来检测该connection是否可用,如果不可用,则通过raise exc.DisconnectionError()来重新从pool中获取可用的connection。 > 这样做会对性能有所损失,建议在频繁切换数据库情况下才加此listener
sqlalchemy中的两类event
通过使用sqlalchemy的listen函数、listens_for装饰器,就可以简单的实现event注册,在对应事件发生时执行指定函数。在sqlalchemy中有两大类event:
Core Events:包括了connection pool lifecycle、sql execution、transaction lifecycle和schema的creation、teardown等事件,参见官方文档
ORM Events:包括了class/object的创建、object的init、attributes on-change、session state/flush/commit、mapper init、object/result的population和object instance的persistence等事件,参见官方文档
上面的代码,其实就是为Core Events中的connection pool lifecycle中,在为checkout注册一个监听函数。
sqlalchemy中的Core Events介绍
Pool的events—sqlalchemy.events.PoolEvents
负责db connection pool的生命周期事件管理,可以通过Pool或者Pool实例来注册事件,还可以使用Engine或Engine实例来注册Pool事件(通过engine.pool获得pool实例)。注册时,主要有两个参数:
PoolEvents中有以下这些事件:
_ConnectionRecord.invalidate()
method is invoked, either from API usage or via “auto-invalidation”. The event occurs before a final attempt to call .close() on the connection occurs其他Core Events
此处着重介绍PoolEvents,还有其他的Core Events,如下:
SQL Execution/Connection中的Events—sqlalchemy.events.ConnectionEvents 负责所有Connectable的事件处理,包括Connection和Engine。
Dialect Events–处理更底层的SQL执行相关的事件
Schema Events—处理model schema相关的事件
sqlalchemy中的ORM Events介绍
Attribute Events — sqlalchemy.orm.events.AttributeEvents
负责model属性相关的事件处理
Mapper Events — sqlalchemy.orm.events.MapperEvents
负责跟ORM model操作相关的事件处理
Instance Events—sqlalchemy.orm.events.InstanceEvents
负责model 实例的事件处理,Instance和Mapper事件类似,但Instance事件更关注model instance的生命周期,而Mapper更关注model持久化系统的事件。
Session Events—sqlalchemy.orm.events.SessionEvents
负责db Session的事件处理