pbp 读取 mysql数据_SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)...
原生session:
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy应用.models import Users
engine = create_engine(
"mysql+pymysql://root:root@127.0.0.1:3306/pro6?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
)
#from sqlalchemy.orm.session import Session
SessionF = sessionmaker(bind=engine)
session = SessionF()
print(session)
obj1 = Users(name='ctz', email='49274573@qq.com', extra='aaaa')
session.add(obj1)
session.commit()
session.close()
问题:由于无法提供线程共享功能,所以在开发时要注意,要给每个线程都创建自己的session
打印sesion可知他是sqlalchemy.orm.session.Session的对象
查看Session的源码 可得到:
class Session(_SessionClassMethods):
"""Manages persistence operations for ORM-mapped objects.
The Session's usage paradigm is described at :doc:`/orm/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')
2.scoped_session
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy应用.models import Users
from sqlalchemy.orm import scoped_session
engine=create_engine(
"mysql+pymysql://root:root@127.0.0.1:3306/pro6?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
)
SessionF=sessionmaker(bind=engine)
#scoped_session封装了两个值 Session 和 registry,registry加括号就执行了ThreadLocalRegistry的__call__方法,如果
# 当前本地线程中有session就返回session,没有就将session添加到了本地线程
#self.registry()=session
session=scoped_session(SessionF)
print(session)
obj1=Users(name='ctz',email='49274573@qq.com',extra='aaaa')
session.remove()
session.query_property()
优点:支持线程安全,为每个线程都创建一个session:
两种方式:通过本地线程Threading.Local()和创建唯一标识的方法(参考flask请求源码)
源码分析:
首先我们在scoped_session中放入了Sesion对象
SessionF=sessionmaker(bind=engine)
session=scoped_session(Session)
一、scoped_session类中
class scoped_session(object):
session_factory = None
def __init__(self, session_factory, scopefunc=None):
#传递过来的那个Session对象
self.session_factory = session_factory
#scopefunc唯一标示函数
if scopefunc:
self.registry = ScopedRegistry(session_factory, scopefunc)
else:
self.registry = ThreadLocalRegistry(session_factory)
第一次进来scopefunc唯一标识为None,我们将Session作为参数传递到ThreadLocalRegistry中,
ThreadLocalRegistry类中
class ThreadLocalRegistry(ScopedRegistry):
"""A :class:`.ScopedRegistry` that uses a ``threading.local()``
variable for storage.
"""
def __init__(self, createfunc):
#传递过来的那个Session对象
self.createfunc = createfunc
self.registry = threading.local()
#scoped_session.registry()后执行
def __call__(self):
try:
#如果本地线程中有值的话直接将值返回,
return self.registry.value
except AttributeError:
#没有值的话就示例话Session(),并将他存到本地线程中,并把实例的对象返回
#相当于Session()后的对象加到了本地线程中
val = self.registry.value = self.createfunc()
return val
其中__call__()只有当scoped_session.registry加括号执行
那我们怎么调用那些方法呢?
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))
其中 Session就是sqlalchemy.orm.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')
在instrument函数中
self.registry()帮我们执行了ThreadLocalRegistry中的___call__方法,拿到了sesion对象
方法源码示例:
def has(self):
return hasattr(self.registry, "value")
def remove(self):
if self.registry.has():
self.registry().close()
self.registry.clear()
实际两种方式原理都是一样的都是第一种,只是第二种将session放到了本地线程中,为每一个进程都设置了一个session,实现了线程安全
pbp 读取 mysql数据_SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)...相关推荐
- java连接本地数据库命令_Java操作数据库时一次连接只能执行一条SQL命令
Java操作数据库时一次连接只能执行一条SQL命令 答:× 全面深化改革要攻坚涉险,必须坚持正确的思想方法,不断探索和把握全面深化改革的内在规律,特别是要把握和处理好全面深化改革中的等重大关系 答:整 ...
- 使用U盘传数据时操作系统做了什么(源码分析)
一.背景 学习linux文件系统时考虑一个具体的问题:我们经常会用U盘传输东西到计算机中.当我们把U盘插入到一台计算机上,并且从U盘中复制文件到计算机里,然后卸载U盘,将U盘拔出.操作系统在这一连串过 ...
- Java Review - 线程池中使用ThreadLocal不当导致的内存泄漏案例源码分析
文章目录 概述 Why 内存泄露 ? 在线程池中使用ThreadLocal导致的内存泄漏 概述 ThreadLocal的基本使用我们就不赘述了,可以参考 每日一博 - ThreadLocal VS I ...
- pbp 读取 mysql数据_pbp: Django项目开发,个人博客网站类。
pbp 项目介绍 首个Django项目开发,个人博客网站类. 框架模型 Django 运行平台 Linux 安装部署 1.安装Python3环境 CentOS 7 curl -o /etc/yum.r ...
- eclipse读取mysql数据乱码_eclipse从数据库获取数据时控制台乱码问题
最近在学习HQL的时候,想从数据库获取数据时eclipse控制台乱码,一开始以为是控制台设置的编码有问题,然后就修改了控制台的编码,run->run Configurations->com ...
- 关于OleDbCommand中操作数据库的几种方法的区别
在vb.net中利用OleDb的OleDbCommand类操作数据库,有以下这些方法: ExecuteNoQuery() 返回值类型integer,常用来执行增删改操作,返回操作影响的行数 Execu ...
- Vue 3 中 v-if 和 v-show 指令实现的原理(源码分析)
前言 又回到了经典的一句话:"知其然,而后使其然".相信大家对 Vue 提供 v-if 和 v-show 指令的使用以及对应场景应该都滚瓜烂熟了.但是,我想仍然会有很多同学对于 v ...
- c 读取mysql中表中数据_c#读取MySQL数据表中的内容
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- php获取mysql数据菜鸟_PHP操作数据库
function con(){ // MYSQL连接参数 $dsn='mysql:host=127.0.0.1;dbname=hello;charset=utf8;port=3306;'; $dbna ...
最新文章
- Mycat实现垂直拆分与水平拆分
- Linux中mysql的操作
- React Native组件开发指南
- nginx源码初读(1)--让烦恼从数据结构开始(ngx_cdecl/ngx_int/ngx_log)
- ubuntu19.10安装haroopad软件
- UVa 11374 机场快线
- python读取math_怎么使用python安装math库?怎么用?
- 记录ie下报XMLHttpRequest: 网络错误 0x80070005, 拒绝访问。
- json生成shp_使用JS把shapefile地图数据转换为geojson格式
- Nginx如何配置静态文件过期时间
- PHP魔术方法和魔法变量详解
- php常用的几个算法
- Dijkstra最短路径
- proteus8找不到isis
- IP变更导致fdfs文件上传服务不可用解决流程
- win10安装串口驱动pl2303 ch340 cp2102时安装不上的一些解决办法
- JavaScript实现左右分栏宽度拉伸
- 如何通过拍照识别植物?试试这几个软件
- 区块链开发先达区块链跨境支付系统解决方案
- 卷积神经网络参数量和计算量内存计算
热门文章
- SpringBoot中常见的错误
- Centos6.5 安装配置docker
- leetcode63. Unique Paths II
- BZOJ2498 : Xavier is Learning to Count
- DRP问题集结(一)-Tomcat无法启动,报错java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory...
- Android系统Google Maps开发实例浅析
- 理解Java动态代理(1)—找我还钱?我出钱要你的命
- html Frame、Iframe、Frameset 的区别 详细出处参考:http://www.jb51.net/web/22785.html
- 干粮 -- 计算机程序设计艺术(The Art of Computer Design) - 2
- 用于参考的学生信息管理系统(数据库简单 可自己参考创建)