一、基于scoped_session实现线程安全
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from models import Users
engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/db_flask", max_overflow=0, pool_size=5)
Session = sessionmaker(bind=engine)
"""
# 线程安全,基于本地线程实现每个线程用同一个session
# 特殊的:scoped_session中有原来方法的Session中的一下方法:
public_methods = (
'__contains__', '__iter__', 'add', 'add_all', 'begin', 'begin_nested',
'close', 'commit', 'connection', 'delete', 'execute', 'expire',
'expire_all', 'expunge', 'expunge_all', 'flush', 'get_bind',
'is_modified', 'bulk_save_objects', 'bulk_insert_mappings',
'bulk_update_mappings',
'merge', 'query', 'refresh', 'rollback',
'scalar'
)
"""
#scoped_session类并没有继承Session,但是却又它的所有方法
session = scoped_session(Session)
# ############# 执行ORM操作 #############
obj1 = Users(name="randy")
session.add(obj1)
# 提交事务
session.commit()
# 关闭session
session.close()
二、底层实现原理
2.1 scoped_session进入类
from sqlalchemy.orm import scoped_session
session = scoped_session(Session)
for meth in Session.public_methods:
setattr(scoped_session, meth, instrument(meth))
public_methods = (
"__contains__",
"__iter__",
"add",
"add_all",
"begin",
"begin_nested",
"close",
"commit",
"connection",
"delete",
"execute",
"expire",
"expire_all",
"expunge",
"expunge_all",
"flush",
"get_bind",
"is_modified",
"bulk_save_objects",
"bulk_insert_mappings",
"bulk_update_mappings",
"merge",
"query",
"refresh",
"rollback",
"scalar",
)
-
首先进入点击scoped_session进入scoped_session类查看如下内容
for meth in Session.public_methods: setattr(scoped_session, meth, instrument(meth))
为scoped_sesion类设置属性
-
public_methods中内容:
这是在Session类中的内容
public_methods = ( "__contains__", "__iter__", "add", "add_all", "begin", "begin_nested", "close", "commit", "connection", "delete", "execute", "expire", "expire_all", "expunge", "expunge_all", "flush", "get_bind", "is_modified", "bulk_save_objects", "bulk_insert_mappings", "bulk_update_mappings", "merge", "query", "refresh", "rollback", "scalar", )
-
setattr(scoped_session, meth, instrument(meth))这句中的instrument是一个闭包函数
改闭包函数中实现了对数据库中具体操作
-
self.registry()中实现如下,为其实现了一个线程
class scoped_session(object): session_factory = None def __init__(self, session_factory, scopefunc=None): self.session_factory = session_factory if scopefunc: self.registry = ScopedRegistry(session_factory, scopefunc) else: self.registry = ThreadLocalRegistry(session_factory)
线程内容如下,最终利用线程中的local()模块中实现线程的安全,也就是操作数据的安全:
class ThreadLocalRegistry(ScopedRegistry): def __init__(self, createfunc): self.createfunc = createfunc self.registry = threading.local()
总结:
- session = scoped_session(Session)这个session是那一个操作过来就是哪一个操作,只操作自己对数据的操作,从而保证了线程的安全