使用Flask-SQLAlchemy进行隔离级别

Thi*_*tin 8 python mysql sqlalchemy flask flask-sqlalchemy

我无法理解数据库隔离级别如何与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'
Run Code Online (Sandbox Code Playgroud)

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

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

app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
Run Code Online (Sandbox Code Playgroud)

我已经定义了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
Run Code Online (Sandbox Code Playgroud)

我尝试使用python终端,即使我读到Read committedSQLAlchemy 的隔离级别,我也面临以下问题.这是我在控制台中的内容:

>>> 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
>>> 
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

谢谢你的帮助!

Rac*_*ers 7

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

db.session.query(Printer).all() 
Run Code Online (Sandbox Code Playgroud)

我想知道是否有两个会话正在进行,一个是您的应用程序设置的,而Printer.query.all()正在与之交谈,以及您在该代码片段中使用的那个会话,您创建的是db = SQLAlchemy ()打电话.

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

  • 真棒!我很高兴.是的,那是对的.如果您查看安装文档(https://pythonhosted.org/Flask-SQLAlchemy/quickstart.html),请注意您创建了db = SQLAlchemy(),然后您的模型继承自db.Model.当您调用MyModel.query.all()时,它会使用该会话.你创建了一个新的会话(完全没问题),但他们不会自动交谈.我相信你可以告诉SQLAlchemy手动过期缓存,但是我不知道这个命令.文档可能有它. (3认同)