SALALchemy Session与scoped_session的源码分析
我们发现Session与scoped_session都有一些方法:
但是scoped_session的源码里面没有设置这些方法让我们从源码里去窥探下源码在哪里设置了这些方法:
Session里面的方法放在了public_methods里面:
scoped_session的源码里面没有这些方法?:
那它怎么实现这些方法的呢?
我们看到了它的构造方法:
def __init__(self, session_factory, scopefunc=None):
"""Construct a new :class:`.scoped_session`. :param session_factory: a factory to create new :class:`.Session`
instances. This is usually, but not necessarily, an instance
of :class:`.sessionmaker`.
:param scopefunc: optional function which defines
the current scope. If not passed, the :class:`.scoped_session`
object assumes "thread-local" scope, and will use
a Python ``threading.local()`` in order to maintain the current
:class:`.Session`. If passed, the function should return
a hashable token; this token will be used as the key in a
dictionary in order to store and retrieve the current
:class:`.Session`. """
self.session_factory = session_factory if scopefunc:
self.registry = ScopedRegistry(session_factory, scopefunc)
else:
self.registry = ThreadLocalRegistry(session_factory)
第一次进来时,scopefunc是空的。
走else,
self.registry = ThreadLocalRegistry(session_factory)
就会实例化:ThreadLocalRegistry。
class ThreadLocalRegistry(ScopedRegistry):
"""A :class:`.ScopedRegistry` that uses a ``threading.local()``
variable for storage. """ def __init__(self, createfunc):
self.createfunc = createfunc
self.registry = threading.local()
里面有两个对象 self.createfunc和registry:
registry是唯一标识,
session加上括号就会执行__call__方法:
因为self.registry.value第一次进入没有值:
所以走except 就是执行self.createfunc()往前找传的值是session_factory那么session_factory是谁呢?就是我们传入的session,也就是实例化了我们的session。
就这就会走下面的方法:
def instrument(name):
def do(self, *args, **kwargs):
return getattr(self.registry(), name)(*args, **kwargs)
return do for meth in Session.public_methods:
setattr(scoped_session, meth, instrument(meth))
方法二:
我们发现
class scoped_session(object):
"""Provides scoped management of :class:`.Session` objects. See :ref:`unitofwork_contextual` for a tutorial. """ session_factory = None
"""The `session_factory` provided to `__init__` is stored in this
attribute and may be accessed at a later time. This can be useful when
a new non-scoped :class:`.Session` or :class:`.Connection` to the
database is needed.""" def __init__(self, session_factory, scopefunc=None):
"""Construct a new :class:`.scoped_session`. :param session_factory: a factory to create new :class:`.Session`
instances. This is usually, but not necessarily, an instance
of :class:`.sessionmaker`.
:param scopefunc: optional function which defines
the current scope. If not passed, the :class:`.scoped_session`
object assumes "thread-local" scope, and will use
a Python ``threading.local()`` in order to maintain the current
:class:`.Session`. If passed, the function should return
a hashable token; this token will be used as the key in a
dictionary in order to store and retrieve the current
:class:`.Session`. """
self.session_factory = session_factory if scopefunc:
self.registry = ScopedRegistry(session_factory, scopefunc)
else:
self.registry = ThreadLocalRegistry(session_factory)
如果我们给
scopefunc传值就会走if语句,
class ScopedRegistry(object):
"""A Registry that can store one or multiple instances of a single
class on the basis of a "scope" function. The object implements ``__call__`` as the "getter", so by
calling ``myregistry()`` the contained object is returned
for the current scope. :param createfunc:
a callable that returns a new object to be placed in the registry :param scopefunc:
a callable that will return a key to store/retrieve an object.
""" def __init__(self, createfunc, scopefunc):
"""Construct a new :class:`.ScopedRegistry`. :param createfunc: A creation function that will generate
a new value for the current scope, if none is present. :param scopefunc: A function that returns a hashable
token representing the current scope (such as, current
thread identifier). """
self.createfunc = createfunc
self.scopefunc = scopefunc
self.registry = {} def __call__(self):
key = self.scopefunc()
try:
return self.registry[key]
except KeyError:
return self.registry.setdefault(key, self.createfunc())
我们看到如果对象加括号就会走__call__方法:
第一次没有值,就会走except,设置并且实例化session。
往下方法和方式一一样啦。
在执行到最后我们要加上一句:
session.remove()
我们来看下这句话做了什么?
def remove(self):
"""Dispose of the current :class:`.Session`, if present. This will first call :meth:`.Session.close` method
on the current :class:`.Session`, which releases any existing
transactional/connection resources still being held; transactions
specifically are rolled back. The :class:`.Session` is then
discarded. Upon next usage within the same scope,
the :class:`.scoped_session` will produce a new
:class:`.Session` object. """ if self.registry.has():
self.registry().close()
self.registry.clear()
我们进入has看下:
def has(self):
return hasattr(self.registry, "value")
如果有值就执行close方法。
然后在执行clear方法:
def clear(self):
try:
del self.registry.value
except AttributeError:
pass
SALALchemy Session与scoped_session的源码分析的更多相关文章
- SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)
原生session: from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine from sqlalch ...
- springMVC源码分析--国际化实现Session和Cookie(二)
上一篇博客springMVC源码分析--国际化LocaleResolver(一)中我们介绍了springMVC提供的国际化的解决方案,接下来我们根据springMVC提供的解决方案来简单的实现一个多语 ...
- [asp.net core 源码分析] 01 - Session
1.Session文档介绍 毋庸置疑学习.Net core最好的方法之一就是学习微软.Net core的官方文档:https://docs.microsoft.com/zh-cn/aspnet/cor ...
- TOMCAT8源码分析——SESSION管理分析(上)
前言 对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿Session用来存放用户登录.身份.权限及状态等信息.对 ...
- Tomcat源码分析——Session管理分析(下)
前言 在<TOMCAT源码分析——SESSION管理分析(上)>一文中我介绍了Session.Session管理器,还以StandardManager为例介绍了Session管理器的初始化 ...
- Tomcat源码分析——Session管理分析(上)
前言 对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿Session用来存放用户登录.身份.权限及状态等信息.对 ...
- 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器
1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...
- Flask框架(三)—— 请求扩展、中间件、蓝图、session源码分析
Flask框架(三)—— 请求扩展.中间件.蓝图.session源码分析 目录 请求扩展.中间件.蓝图.session源码分析 一.请求扩展 1.before_request 2.after_requ ...
- Flask框架(五) —— session源码分析
Flask框架(五) —— session源码分析 目录 session源码分析 1.请求来了,执行__call__方法 2.__call__方法 3.调用__call__方法 3.1.ctx = s ...
随机推荐
- ELK(elasticsearch+kibana+logstash)搜索引擎(一): 环境搭建
1.ELK简介 这里简单介绍一下elk架构中的各个组件,关于elk的详细介绍的请自行百度 Elasticsearch是个开源分布式搜索引擎,是整个ELK架构的核心 Logstash可以对数据进行收集. ...
- js 计算快速统计中用到的日期
前言 最近在做统计报表模块,其中查询条件用到了快速查询,主要为了方便客户统计查询常用的几个日期纬度,比如本周.上周.本月.上月.昨日. 使用js计算,主要用到了js Date. getDate().g ...
- Java框架之Spring(三)
本文主要介绍Spring中, 1 Bean 的 init-method 和 destroy-method 2 集合类型的装配 3 注解方式装配 4 以自动扫描把组件纳入spring容器中管理 5 代理 ...
- Cylinder Candy(积分+体积+表面积+旋转体)
Cylinder Candy Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge Edward the confectioner is ...
- 网页三剑客:HTML+CSS+JavaScript 之CSS概述
CSS 简介 什么是 CSS? CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是 ...
- Spark jdbc postgresql数据库连接和写入操作源码解读
概述:Spark postgresql jdbc 数据库连接和写入操作源码解读,详细记录了SparkSQL对数据库的操作,通过java程序,在本地开发和运行.整体为,Spark建立数据库连接,读取数据 ...
- MVC与单元测试实践之健身网站(八)-统计分析
统计分析模块与之前的内容相对独立,用于记录并跟踪各部位围度的变化.还需提供对所作计划的分析,辅助使计划更合理. 一 围度记录 这儿可以记录各项身体围度指标,现在包括体重在内身体上上下下基本全部提供了 ...
- (网页)JS实现alert中显示换行的方法
转自脚本之家: 这篇文章主要介绍了JS实现alert中显示换行的方法,实例分析了两种实现alert换行的实现技巧,非常简单实用,需要的朋友可以参考下 本文实例讲述了JS实现alert中显示换行的方法. ...
- 理解ES6中的Promise
一.Promise的作用 在ajax请求数据的过程中,我们可以异步拿到我们想要的数据,然后在回调中做相应的数据处理. 这样做看上去并没有什么麻烦,但是如果这个时候,我们还需要做另外一个ajax请求,这 ...
- Scala并发编程【消息机制】
1.入门 package actor import scala.actors.Actor import scala.actors.migration.ActorDSL /** * Created by ...