此文为本人原创,最早发布于求助《Flask Web 开发》第五章关于数据库db.session.add()和db.session.commit()问题。
问题简述:
当加入了
SQLALCHEMY_COMMIT_ON_TEARDOWN=True
,在什么情况下仍然要执行db.session.commit()
解答整理如下:
config
是在app/__init__.py
中调用的,所以执行model.py
中的方法时,SQLALCHEMY_COMMIT_ON_TEARDOWN = True
已经生效了。即请求结束后自动commit。
后面几个章节中出现db.session.commit()
的主要作用都是为了生成id来使用。
你可以结合源码看一下。
session的原理就请参考Flask 源码阅读笔记。
SQLALCHEMY_ON_TEARDOWN
在flask-sqlalchemy 2.0之后已经被删除了,需要用SQLALCHEMY_TRACK_MODIFICATIONS
替代,想必你运行的时候应该看到过相关提示。
这个新熟悉我还没掌握,抽空看下documentation再来分析。
继续回到SQLALCHEMY_ON_TEARDOWN
。按照书上的说法:
将其设为True时,每次请求结束后都会自动提交数据库中的变动。
因为v1.0的如果这里的documentation已经找不到了,没有依据,我就在这推测一下:
只有当请求结束的时候,才会自动commit
,而直接操作数据库是不行的,需要手动commit
。
回到model.py中看,insert_roles()
被@staticmethod
包装,是一个静态方法,它执行的位置是在python manage.py shell
中,而非请求中,所以需要手动commit
。
你可以验证一下,方法也很简单,保证写入SQLALCHEMY_ON_TEARDONW=True
后,在shell中尝试:
>>> user = User(username='test')
>>> db.session.add(user)
>>> quit()
再次进入shell,查找<User u'test'>
,不存在,即推断合理:shell中执行的用于操作数据库的方法还是要加commit
。