SQLAlchemy 合并()不使用烧瓶工作
Posted
技术标签:
【中文标题】SQLAlchemy 合并()不使用烧瓶工作【英文标题】:SQLAlchemy merge() not working using flask 【发布时间】:2013-01-31 04:12:13 【问题描述】:我正在学习如何使用 sqlalchemy,并且正在开发小型应用程序。我在尝试使用 ORM 更新存储在数据库中的数据时遇到一些问题。我不确定我错过了什么。表单edit_product.html
填充了正确的数据,但是return redirect(url_for
语句在不更新数据的情况下被触发。我正在使用merge(),我尝试按照一些教程的建议使用add()
,但是如果我这样做,我会收到一条错误消息,指出记录已经存在。
这是我在views.py
中的edit_product
函数:
from database import db_session
@app.route('/product/edit/<int:product_id>', methods=['GET', 'POST'])
def edit_product(product_id):
product = Product.query.filter(Product.id == product_id).first()
form = NewOtrosForm(obj=product)
if request.method == 'POST':
print request.form
if form.validate():
form.populate_obj(product)
db_session.commit()
return redirect(url_for('product'))
else:
return render_template('edit_product.html', form=form)
这是我在 jinja2 模板中的编辑表单中的内容:
% from "_formhelpers.html" import render_field %
<form method=post action="">
<dl>
render_field(form.name)
render_field(form.price)
render_field(form.description)
render_field(form.provider)
render_field(form.detalles)
</dl>
<p><input type="submit" value="Save Changes"></p>
</form>
【问题讨论】:
【参考方案1】:您可以尝试更改以下内容吗:
form = NewOtrosForm(obj=product)
到:
form = NewOtrosForm(request.form, obj=product)
【讨论】:
谢谢@codegeek - 我尝试使用你的建议,但它返回AttributeError: 'Request' object has no attribute 'POST'
。
你使用的是 WTForms 还是 Flask-WTForms ?
我正在使用 wtforms。通过使用request.form
,它被修复了。谢谢!【参考方案2】:
您不需要在这里使用merge()
,它的目的是将状态从外部对象转移到会话中的新实例或已经存在的实例。您的product
对象已经属于会话,因此调用form.populate_obj(product)
(更改为product
在此会话中将其标记为“脏”)和之后调用db_session.commit()
就足够了。
【讨论】:
感谢您的回复 Audrius – 我已实施您的建议,但仍未处理更新。我已根据您的建议更新了反映我所做更改的代码。这可能是模型类本身的问题吗?我正在使用继承。提前致谢。 可能是product
没有被修改,所以commit()
看不到任何变化并且什么也不做。尝试在form.populate_obj(product)
之后检查db_session.dirty
,如果确实被修改,它应该包含product
。
我试过dirty
,但也没有任何反应。我也尝试过调用名为Otros
的子类,但它也不起作用。你对为什么product
没有被修改有什么建议吗?
我的猜测是您的form
没有从POST
请求中获取数据,并且由于您已经从product
(NewOtrosForm(obj=product)
) 中为其提供了值,因此相同的数据是正在验证并返回给product
。因为是相同的数据,db_session
看不到任何变化,也不会在commit()
上发出UPDATE
。以上是关于SQLAlchemy 合并()不使用烧瓶工作的主要内容,如果未能解决你的问题,请参考以下文章
使用来自 SQLAlchemy 对象的数据在烧瓶中预填充 WTforms
create_engine 中的烧瓶 SQLAlchemy KeyError 'False'