关于flask-sqlalchemy的用法研究
最近使用到flask的sqlalchemy,因为flask对sqlalchemy做了一些封装,加上自己本身对sqlalchemy也不熟悉,用法上走了很多弯路。
因为没时间去研究sqlalchemy的源码,所以只能简单的测试下用法。
1、flask-sqlalchemy是线程安全的
具体可以参考文章 https://blog.csdn.net/luffyser/article/details/89380186
2、每次查询完以后,记得commit,不然会占用连接池
我在本地做了个简单的测试,如果单次查询请求完,不commit的话,连续请求几次,再发起request就没有响应了,推测是数据库连接池没释放,被占用。导致请求数据库挂起,从而导致没有response。
每次请求完,直接commit,可以解决此问题。
def queryLast(cls):
try:
ret = db.session.query(cls).order_by(cls.version.desc()).first()
#db.session.expunge(ret)
db.session.commit()
except:
db.session.rollback()
ret = None return ret
3、但是,如果Commit后,查询结果可能会从缓存中清掉,如果再使用查询结果的对象,还会再次建立连接查询。所以还会出现上述连接池耗尽的问题。
从下图标黄的日志可以看出,commit后,使用返回的查询结果时,又执行了一次查询任务,并返回结果,my god!
2019-12-10 12:31:21,650 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2019-12-10 12:31:21,651 INFO sqlalchemy.engine.base.Engine SELECT appversion.id AS appversion_id, appversion.version AS appversion_version, appversion.`appUrl` AS `appversion_appUrl`, appversion.des AS appversion_des, appversion.`createTime` AS `appversion_createTime`, appversion.`lastModiftyTime` AS `appversion_lastModiftyTime`, appversion.type AS appversion_type
FROM appversion ORDER BY appversion.version DESC
LIMIT %s
2019-12-10 12:31:21,651 INFO sqlalchemy.engine.base.Engine (1,)
2019-12-10 12:31:21,661 INFO sqlalchemy.engine.base.Engine COMMIT
2019-12-10 12:31:21,680 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2019-12-10 12:31:21,681 INFO sqlalchemy.engine.base.Engine SELECT appversion.id AS appversion_id, appversion.version AS appversion_version, appversion.`appUrl` AS `appversion_appUrl`, appversion.des AS appversion_des, appversion.`createTime` AS `appversion_createTime`, appversion.`lastModiftyTime` AS `appversion_lastModiftyTime`, appversion.type AS appversion_type
FROM appversion
WHERE appversion.id = %s
2019-12-10 12:31:21,681 INFO sqlalchemy.engine.base.Engine (1,)
4、但有时候(可能是时间略长些)commit后,再使用查询结果的对象,可能会出现报错:Instance <User at 0x32768d0> is not bound to a Session
此种情况可能是因为绑定的session已经被回收,导致无法再进行查询,所以出错。
5、综上所述,为安全起见,需要在查询结果后,加上 db.session.expunge(ret),断开查询结果与session的关系。让它成为一个本地实体,不会从缓存中清除,使用时候,就不会再查询。
6、但测试时候发现一个奇怪的问题,另外一个获取user的接口,和上面的代码几乎没什么区别,居然会自动rollback,这个让我百思不得其解。
我的逻辑是取到查询结果(即用户)后,判断用户的状态字段是否为1,如果为1,就修改用户属性,然后commit,如果不是1,就不做操作,也没有调用rollback。
但是我测试时候发现,如果不是1的时候,它会自动rollback。
或许这是sqlalchemy的高级功能?
7、总结:
1、sqlalchemy的对象实体(model),和session建立了联系,你get、set这些model的时候,就算已经commit,也会重新自动和数据库建立连接(get的时候会重新select、set的时候会重新建立连接,等待你提交,如果你不提交,这个连接一直存在,最终会耗尽。),所以要谨慎使用model的字段,除非你确实明白自己在做什么,会发生什么。
2、使用db.session.expunge会切断实体和session的关系。这个是个不错的用法。
3、但我还是强烈建议自己再搞一套model,来做业务层逻辑。sqlalchemy的对象实体仅用来做数据库的操作。这样会避免很多时候,连接不小心没释放的坑。
关于flask-sqlalchemy的用法研究的更多相关文章
- flask SQLAlchemy中一对多的关系实现
SQLAlchemy是Python中比较优秀的orm框架,在SQLAlchemy中定义了多种数据库表的对应关系, 其中一对多是一种比较常见的关系.利用flask sqlalchemy实现一对多的关系如 ...
- flask, SQLAlchemy, sqlite3 实现 RESTful API 的 todo list, 同时支持form操作
flask, SQLAlchemy, sqlite3 实现 RESTful API, 同时支持form操作. 前端与后台的交互都采用json数据格式,原生javascript实现的ajax.其技术要点 ...
- flask建表遇到的错误: flask,sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (1071, 'Specified key was too long; max key length is 767 bytes')
error:flask,sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (1071, 'Specifie ...
- Flask – SQLAlchemy成员增加
目录 简介 结构 展示 技术 运行 代码 创建数据库表单 views视图 home主页 添加成员addnew.html 展示页show_all 简介 结构 $ tree -I "__pyca ...
- 关于Python的super用法研究
一.问题的发现与提出 在Python类的方法(method)中,要调用父类的某个方法,在python 2.2以前,通常的写法如代码段1: 代码段1: class A: def __init__(se ...
- Flask+SQLAlchemy+alembic+Flask-RESTful使用
前言 其实准备把这篇删掉,先写Flask-restful相关的,后来想想大体框架还是先写出来,这两天踩了很多坑,有的谷歌也没有答案.一直摸索也总算是开始了. 正文 SQLAlchemy/alembic ...
- flask SQLALchemy外键及约束
from flask import Flask,session from flask_sqlalchemy import SQLAlchemy import config app = Flask(__ ...
- python3 + flask + sqlalchemy +orm(3):多对多关系
一篇文章有多个tag,一个tag也可以属于多篇文章,文章和tag存在多对多关系 config.py DEBUG = True #dialect+driver://root:1q2w3e4r5t@127 ...
- python3 + flask + sqlalchemy +orm(2):数据库中添加表
往数据库中添加一张保存文章的表,表明为article,字段有id,title,content 同样一个配置文件:config.py DEBUG = True #dialect+driver://roo ...
随机推荐
- 自己实现 aop 和 spring aop
上文说到,我们可以在 BeanPostProcessor 中对 bean 的初始化前化做手脚,当时也说了,我完全可以生成一个代理类丢回去. 代理类肯定要为用户做一些事情,不可能像学设计模式的时候创建个 ...
- thinkphp分页样式css代码
<style type="text/css"> .Pagination a:hover,.current{background-color: #f54281;borde ...
- B2B电商正在向一个新的方向转变
在互联网+.中国制造2025等国家战略规划的不断催发下,淡出舆论风口多时的B2B电商,开始重新回归公众视野,B2B行业也就此得到一剂强心剂.不过值得关注的是,B2B平台商业模式已经开始发生变革. 互联 ...
- jenkins手把手教你从入门到放弃01-jenkins简介(详解)
一.简介 jenkins是一个可扩展的持续集成引擎.持续集成,也就是通常所说的CI(Continues Integration),可以说是现代软件技术开发的基础.持续集成是一种软件开发实践, 即团队开 ...
- 06_K-近邻算法
k-近邻算法 算法介绍 定义: 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一类别,则该样本也属于这个类别. 计算距离公式:欧式距离 (两点之间距离) 需要做标准化 ...
- Python print函数使用
本文链接:https://www.cnblogs.com/zyuanlbj/p/11905405.html 函数定义 def print(self, *args, sep=' ', end='\n', ...
- 力扣(LeetCode)验证回文串 个人题解(C++)
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写. 说明:本题中,我们将空字符串定义为有效的回文串. 示例 1: 输入: "A man, a plan, a c ...
- Java描述设计模式(23):访问者模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 电竞是游戏比赛达到"竞技"层面的体育项目.利用电子设备作为运动器械进行的.人与人之间的智力对抗 ...
- Oracle数据库 获取CLOB字段存储的xml格式字符串指定节点的值
参照: Oracle存储过程中使用游标来批量解析CLOB字段里面的xml字符串 背景:在写存储过程时,需要获取表单提交的信息.表单信息是以xml格式的字符串存储在colb类型的字段dataxml中,如 ...
- vscode在终端运行脚本时出现“因为在此系统上禁止运行脚本”
首先关闭vscode,再以管理员的身份运行vscode,然后打开终端执行: get-ExecutionPolicy,显示的是Restricted,表示状态是禁止的; 再执行:set-Execution ...