背景:Flask/Flask-SQLAlchemy/Flask-WTF,使用声明式和作用域 session
简单的POST
操作:
@tas.route('/order_add', methods=['GET', 'POST'])
def tas_order_add():
if request.method == 'POST':
order_form = OrderForm()
if order_form.validate_on_submit():
order = Order()
order_form.populate_obj(order)
db_session.add(order)
db_session.commit()
现在尝试运行它时出现错误:
InvalidRequestError: Object '' is already attached to session '1' (this is '2')
将 add 更改为 merge 解决了问题,但是:
- 我不知道为什么我刚启动一个对象就必须合并它
如果我确实更改了 add 以合并并尝试定义其中一个属性,那么
order = Order() order_form.populate_obj(order) order.order_status = OrderStatus.query.filter(OrderStatus.code=='PLACED').first() db_session.merge(order) db_session.commit()
我得到同样的错误,只是现在在 OrderStatus 对象上
InvalidRequestError: Object '' is already attached to session '2' (this is '1')
谁能指出我做错了什么,因为这让我抓狂。我确实有一些使用 SQLAlchemy 的经验,但这是我第一次看到这种行为,我无法查明问题所在。
搜索所有我发现的是双重数据库 session 初始化的问题,但我不相信这是这种情况。
编辑
db_session 在单独的文件 database.py 中定义,内容如下
from sqlalchemy.engine import create_engine
from sqlalchemy.ext.declarative.api import declarative_base
from sqlalchemy.orm.scoping import scoped_session
from sqlalchemy.orm.session import sessionmaker
engine = create_engine('sqlite:///fundmanager_devel.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
最佳答案
似乎是 session 混淆的问题,我按如下方式使用它并且有效:
from <project> import db
from <project.models import Category
category = QuerySelectField('category', query_factory=lambda: db.session.query(Category), get_pk=lambda a: a.id, get_label=lambda a: a.name)
关于python - SQLAlchemy session 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19769841/