Flask-SQLAlchemy 的隔离级别

Posted

技术标签:

【中文标题】Flask-SQLAlchemy 的隔离级别【英文标题】:Isolation level with Flask-SQLAlchemy 【发布时间】:2014-09-21 08:32:28 【问题描述】:

我无法理解数据库隔离级别如何与 Flask-SQLAlchemy 一起使用,尤其是如何真正提交更改或关闭会话。这是我的问题的背景:

我将 Flask-SQLAlchemy 用于带有 mysql 数据库的 Flask 项目。 这是我的项目的配置方式

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://user:passwd@localhost/mydb'
SQLALCHEMY_MIGRATE_REPO = '/path/to/myapp/db_repository'

CSRF_ENABLED = True
SECRET_KEY = 'this is a secret'

在我的__init__.py 文件中创建db 对象:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
import config

app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)

我已经定义了Printer一等模型:

from myapp import db
...
class Printer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(120))

    def __init__(self, name):
        self.name = name

我尝试使用 python 终端,即使我阅读了 SQLAlchemy 的Read committed 隔离级别,我也面临以下问题。这是我的控制台中的内容:

>>> from myapp import app
>>> from myapp.models import Printer
>>> import config
>>> from flask.ext.sqlalchemy import SQLAlchemy
>>> app.config.from_object('config')
>>> db = SQLAlchemy(app)
>>> for printer in Printer.query.all():
...     print printer.name
...
Circle
Mww
>>> p = Printer('dummy')
>>> db.session.add(p)
>>> db.session.commit()
>>> for printer in Printer.query.all():
...     print printer.name
...
Circle
Mww
>>> 

当我查找数据库时,我的更改已提交:

mysql> SELECT * FROM printer;
+----+--------+
| id | name   |
+----+--------+
|  1 | Circle |
|  2 | Mww    |
|  3 | dummy  |
+----+--------+
3 rows in set (0.00 sec)

如果我退出我的 python 终端,再次打开它并使用 Printer.query.all() 读取结果,我的更改就会出现。

虽然我了解 SQLAlchemy 等待提交更改和/或关闭会话,但我不明白为什么我无法在 db.session.commit() 语句之后读取我的更改,也不知道如何关闭会话(我试过db.session.close(),之后读取数据库并没有得到更好的结果)

感谢您的帮助!

【问题讨论】:

【参考方案1】:

如果使用 SQLAlchemy 版本的查询会发生什么?

db.session.query(Printer).all() 

我想知道是否有两个会话正在进行:

    您的应用设置的 Printer.query.all() 正在与之交谈的对象 你在那个由db = SQLAlchemy() 调用创建的 sn-p 中使用的那个

这可以解释为什么db.session.commit() 没有刷新Printer.query.all() 拥有的数据。

【讨论】:

你成就了我的一天。尽管如此,我还是想真正了解这里发生了什么:设置db 对象会创建一个会话,而从 Model.query 函数创建的任何请求都会创建其他并发会话? 太棒了!我很高兴。是的,没错。如果您查看设置文档 (pythonhosted.org/Flask-SQLAlchemy/quickstart.html),请注意您创建了 db = SQLAlchemy(),然后您的模型继承自 db.Model。当您调用 MyModel.query.all() 它使用该会话。您创建了一个新会话(完全可以),但他们不会自动交谈。不过,我相信您可以告诉 SQLAlchemy 手动使缓存过期,但我不知道该命令。文档可能有它。 非常感谢您的帮助,我会阅读文档的。令人印象深刻的简历顺便说一句,对我们学生很有启发! 我在 EC2 上运行的烧瓶服务器上面临完全相同的问题。而它在我的本地机器上工作正常。即使在像这样***.com/a/21917724/5167801 这样的会话到期后也没有工作。你成功了吗? 更新:我的问题是,我正在使用 3 个工作人员运行带有 guniwork 网络服务器的烧瓶应用程序,并且所有三个工作人员的缓存都不相同。将它们减少到 1 个已解决。

以上是关于Flask-SQLAlchemy 的隔离级别的主要内容,如果未能解决你的问题,请参考以下文章

事务的隔离级别和mysql事务隔离级别修改

MySQL 四种事务隔离级的说明

MySQL 四种事务隔离级的说明[转]

如何确认当前事务的隔离级别

MySQL数据库事务隔离级别

修改mysql事务隔离