我们发现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的源码分析的更多相关文章

  1. SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)

    原生session: from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine from sqlalch ...

  2. springMVC源码分析--国际化实现Session和Cookie(二)

    上一篇博客springMVC源码分析--国际化LocaleResolver(一)中我们介绍了springMVC提供的国际化的解决方案,接下来我们根据springMVC提供的解决方案来简单的实现一个多语 ...

  3. [asp.net core 源码分析] 01 - Session

    1.Session文档介绍 毋庸置疑学习.Net core最好的方法之一就是学习微软.Net core的官方文档:https://docs.microsoft.com/zh-cn/aspnet/cor ...

  4. TOMCAT8源码分析——SESSION管理分析(上)

    前言 对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿Session用来存放用户登录.身份.权限及状态等信息.对 ...

  5. Tomcat源码分析——Session管理分析(下)

    前言 在<TOMCAT源码分析——SESSION管理分析(上)>一文中我介绍了Session.Session管理器,还以StandardManager为例介绍了Session管理器的初始化 ...

  6. Tomcat源码分析——Session管理分析(上)

    前言 对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿Session用来存放用户登录.身份.权限及状态等信息.对 ...

  7. 一个由正则表达式引发的血案 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. 一些特殊字符,如“&”,“- ...

  8. Flask框架(三)—— 请求扩展、中间件、蓝图、session源码分析

    Flask框架(三)—— 请求扩展.中间件.蓝图.session源码分析 目录 请求扩展.中间件.蓝图.session源码分析 一.请求扩展 1.before_request 2.after_requ ...

  9. Flask框架(五) —— session源码分析

    Flask框架(五) —— session源码分析 目录 session源码分析 1.请求来了,执行__call__方法 2.__call__方法 3.调用__call__方法 3.1.ctx = s ...

随机推荐

  1. 精读JavaScript模式(六),Memoization模式与函数柯里化的应用

    假期就这么结束了!十天假就有三天在路上,真的难受!想想假期除了看了两场电影貌似也没做什么深刻印象的事情.流浪地球,特效还是很赞,不过对于感情的描写还是逃不掉拖沓和尴尬的通病,对于国产科幻还是抱有支持的 ...

  2. 一段有意思的fork()程序

    献上代码,不成敬意: #include <unistd.h> #include <stdio.h> int main() { int i = 0; if(fork()) i++ ...

  3. HTML 中获取现在时间,实时时间获取

    JavaScript   Date 对象 Date 对象用于处理日期与实际. 创建 Date 对象: var now  =  new Date(). 方法 描述 getDate() 从 Date 对象 ...

  4. MySQL学习(四) SQL连接查询

    更多情况下,我们查询的数据来源于多张表,所有有必要了解一下MySQL中的连接查询. SQL中将连接查询分成四类:交叉连接,内连接,外连接和自然连接. 数据准备 student表 -- -------- ...

  5. Docker 修改存储路径

    Docker 版本 1.13 及以下 systemctl stop docker.service cp /usr/lib/systemd/system/docker.service /home/doc ...

  6. web print

    <!doctype html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  7. vue项目导入外部css样式和js文件

    <template> <div id="app" > </div> </template> <script src=" ...

  8. Spark 跑 java 示例代码

    一.下载示例代码: git clone https://github.com/melphi/spark-examples.git 从示例代码中可以看到 pox中引入了 Spark开发所需要的依赖. 二 ...

  9. 【读书笔记】iOS-iOS流媒体

    在网络上直接看电影已经不是什么新鲜的事情,在iOS等移动设备上也有很多在线视频应用,如国内的PPS和PPLive应用,还有一些新闻视频都可以在线观看,如USA TODY.所以这些在线视频都采用流媒体技 ...

  10. JavaSE——UDP协议网络编程(二)

    在 UDP 网络编程中,发送方与接收方没有建立联系,没有明显的服务器端和客户端的区别. 类 DatagramSocket: 此类表示用来发送和接收数据报包的套接字. 主要的构造方法: Datagram ...