系列文章:

  1. Python SQLAlchemy入门教程

概念

session用于创建程序和数据库之间的会话,所有对象的载入和保存都需通过session对象 。

通过sessionmaker调用创建一个工厂,并关联Engine以确保每个session都可以使用该Engine连接资源:

from sqlalchemy.orm import sessionmaker

# 创建session
DbSession = sessionmaker(bind=engine)
session = DbSession()

操作

session的常见操作方法包括:

  1. flush:预提交,提交到数据库文件,还未写入数据库文件中
  2. commit:提交了一个事务,把内存的数据直接写入数据库
  3. rollback:回滚
  4. close:关闭

在事务处理时,需注意一下两点:

  1. 在事务处理过程发生异常时,进行rollback操作,否则会在下次操作时报错:
Can’t reconnect until invalid transaction is rolled back
  1. 一般情况下,在一个事务处理完成之后要关闭session,以确保数据操作的准确性。

建议封装上下文方法:

from contextlib import contextmanager

@contextmanager
def session_maker(session=session):
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()

调用:

def update_user():
with session_maker() as db_session:
db_session.query(Users).filter_by(name='test2').update({'email': 'test2@qq.com'})

线程安全

session不是线程安全的,并且我们一般session对象都是全局的,那么在多线程情况下,当多个线程共享一个session时,数据处理就会发生错误。

为了保证线程安全,需使用scoped_session方法:

db_session = scoped_session(sessionmaker(bind=engine))

内部原理

session对象包含了三个重要的部分:

  1. 标识映射(Identity Map)
  2. 对象的状态 / 状态跟踪
  3. 事务

标识映射

标识映射是与ORM关联的集合,通过标识映射保证了数据库操作的准确性。

具体的实现原理是:维护一个Python字典(IdentityMap),关联这个Session对象到数据库ID的映射,当应用程序想要获取一个session对象时,若该对象不存在,标识映射会加载该对象并缓存,若该对象已存在,则直接获取。这样的好处是:

  1. 已经被请求过的session对象缓存下来,不需要连接加载多次,造成额外的开销;
  2. 避免了数据不一致

状态跟踪

一个Session对象从创建到销毁,依次经历四种状态,分别是:

  1. Transient:刚new出来的对象,还不在会话中,也没有保存到数据库。
  2. Pending:transient的对象调用add后,就会变成pending状态,这时会加入sqlalchemy的监管范围,数据并未更新到数据库。
  3. Persistent:该状态表明数据库里已经记录了该对象,在两种情况下对象处于该状态:一是通过flush()方法刷新pending对象,二是从数据库query()得到对象。
  4. Detached:在会话中的事务提交之后,所有的对象都将是Detached状态。

所谓的状态跟踪,就是跟踪以上四个状态,保证数据的准确性并在合理的时机丢弃对象以保证合理开销,那么具体是怎么实现的呢?

我们可以看到,只有在pending状态时,对象的内存数据和数据库中的数据不一致,在Persistent状态时,内存数据和数据库数据已经一致,那么此后任意时刻丢弃该对象数据都是可以的,这时就需要找个合适的时机丢弃对象,过早或过晚都有其缺陷。于是,就让垃圾回收器来做决定,在内存不够的时候释放对象,回收内存。

Session对象采用了弱引用机制,所谓弱引用,就是说,在保存了对象的引用的情况下,对象仍然可能被垃圾回收器回收。在某一时刻通过引用访问对象时,对象可能存在也可能不存在,如果对象不存在,就重新从数据库中加载对象。而如果不希望对象被回收,只需要另外保存一个对象的强引用即可 。

session对象包括三个属性:

  1. new:刚加入会话的对象
  2. dirty:刚被修改的对象
  3. deleted:在会话中被删除的对象

三个属性共同的特点就是内存的数据和数据库数据不一致,也就是对象处于pending状态,这也就表明了session保存了所有对象处于pending状态的强引用。

以上。

代码可参照:my github

SQlALchemy session详解的更多相关文章

  1. 【Hibernate】Hibernate系列2之Session详解

    Session详解 2.1.概述-一级缓存 2.2.操作session缓存方法 2.3.数据库隔离级别 2.4.持久化状态 2.5.状态转换 2.6.存储过程与触发器

  2. PHP5 session 详解【经典】 -- 转帖

    PHP5 session 详解[经典] http协议是WEB服务器与客户端(浏览器)相互通信的协议,它是一种无状态协议.所谓无状态,指的是不会维护http请求数据,http请求是独立的,非持久的.而越 ...

  3. Cookie与Session详解

    来源:<PHP核心技术与最佳实践> 列旭松 陈文 著 Cookie与Session详解读书笔记,从概念.操作.应用.注意事项以及区别等几方面详细阐述两者的基础知识,它们都是针对HTTP协议 ...

  4. orakill和ALTER SYSTEM KILL SESSION详解

    --orakill和ALTER SYSTEM KILL SESSION详解[转]-----------------------------------------2013/11/05 一个用户进程偶尔 ...

  5. 巨人大哥谈Web应用中的Session(session详解)

    巨人大哥谈Web应用中的Session(session详解) 虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术. ...

  6. 网络基础 http 会话(session)详解

    http 会话(session)详解 by:授客 QQ:1033553122 会话(session)是一种持久网络协议,在用户(或用户代理)端和服务器端之间创建关联,从而起到交换数据包的作用机制 一. ...

  7. JavaWeb Session详解

    代码地址如下:http://www.demodashi.com/demo/12756.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + ## Session的由来 上一篇博文介绍 ...

  8. 引用 Session详解 作者:郎云鹏

    本文转载自leeldy<Session详解 作者:郎云鹏>   引用 leeldy 的 Session详解 作者:郎云鹏 目录: 一.术语session 二.HTTP协议与状态保持 三.理 ...

  9. ASP.NET Session详解(转)

    ASP.NET Session详解 本文章来自:http://blog.163.com/adam601@126/blog/static/22506317200932824210996/ 当用户在 We ...

随机推荐

  1. 比较两个文件的异同Python3 标准库difflib 实现

    比较两个文件的异同Python3 标准库difflib 实现 对于要比较两个文件特别是配置文件的差异,这种需求很常见,如果用眼睛看,真是眼睛疼. 可以使用linux命令行工具diff a_file b ...

  2. 弄明白CMS和G1,就靠这一篇了

    目录 1 CMS收集器 安全点(Safepoint) 安全区域 2 G1收集器 卡表(Card Table) 3 总结 4 参考 在开始介绍CMS和G1前,我们可以剧透几点: 根据不同分代的特点,收集 ...

  3. [UWP]使用CompositionLinearGradientBrush实现渐变画笔并制作动画

    1. 什么是 CompositionBrush CompositionBrush(合成画笔)是操作可视化层时用于绘制 SpriteVisual 区域的画笔. 使UWP 应用时可以选择使用 XAML 画 ...

  4. 解决Anki服务器同步问题:坚果云 & Floder sync (已测试)

    读前须知: 更新日期:2019-07-08 1.本教程面向对象为:有一定计算机知识人群 2.配合参考链接中的文章,共同食用. 3.已经过测试,可同步图片,音频,视频 4.尝试有风险,提前导出Anki卡 ...

  5. Excel接口导出,导入数据库(.Net)

    public ActionResult TestExcel(string filePath) { return View(); } /// <summary> /// 根据Excel列类型 ...

  6. Springboot 系列(十五)如何编写自己的 Springboot starter

    1. 前言 Springboot 中的自动配置确实方便,减少了我们开发上的复杂性,那么自动配置原理是什么呢?之前我也写过了一篇文章进行了分析. Springboot 系列(三)Spring Boot ...

  7. (day33)数据库

    目录 1. 数据库是什么 2. 为什么使用数据库 3. 数据库的分类 1. 关系型数据库 2. 非关系型数据库 4. mysql的架构 5. mysql的安装 1. windows的安装 2. win ...

  8. Unity系统消息广播

    # 1.前言Unity自带消息系统,如SendMessage等,此方法利用的反射,且会反射游戏物体上的所有组件,对性能不友好.而且由于参数为方法名称,所以如果使用代码混淆,则会无法调用 方法,且难以追 ...

  9. 在移动硬盘中安装win10和macos双系统

    本文通过在SSD移动硬盘中安装win10和macos双系统,实现操作系统随身携带 小慢哥的原创文章,欢迎转载 目录 ▪ 目标 ▪ 准备工作 ▪ Step1. 清空分区,转换为GPT ▪ Step2. ...

  10. IIS中如何设置域名

    如何在IIS中设置域名: 1,想好我们想要配置的本地域名,我们以www.baidu.com为例. 2,打开系统盘,一般默认的系统盘为C盘,打开:C:\Windows\System32\drivers\ ...