停止 SQLAlchemy 更新已从数据库中提取的行
Posted
技术标签:
【中文标题】停止 SQLAlchemy 更新已从数据库中提取的行【英文标题】:Stop SQLAlchemy from updating rows that have already been pulled from the database 【发布时间】:2013-07-02 21:11:44 【问题描述】:我正在为网站创建一个简单的通知系统。用户的通知从数据库中提取,如果它们还没有被标记为已看到,然后显示给用户。看不见的以粗体显示。这是我的一些代码:
query = request.db.query(Notification)\
.filter(Notification.user == request.user)
notifications = query.order_by(Notification.created_at.desc()).all()
print [ notif.seen for notif in notifications ] # [ False, False, False... ]
query.filter(Notification.seen == False).update(
'seen': True
)
request.db.commit()
print [ notif.seen for notif in notifications ] # [ True, True, True... ]
您会从我的打印语句中注意到 notifications
在执行 update
查询时被修改,尽管已经使用 .all()
从数据库中提取。
我不想要这种行为。我需要查看notifications
是,而不是是,以便将以前未见过的字段加粗。
查看文档,我认为将 synchronize_session
参数设置为 False
可能会起作用。
query.filter(Notification.seen == False).update(
'seen': True
, False)
但不幸的是,它没有。
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:synchronize_session=False 就像你正在做的那样,但你也需要在查看通知之前不提交,或者在你的会话中打开 expire_on_commit=False 。该对象通常在提交后首次访问时从数据库中刷新。
【讨论】:
【参考方案2】:我认为在这里做任何太棘手的事情(例如中断同步或从会话中删除对象)是不值得的。在这种情况下,最好保存一个事先看不到的通知列表,然后在您的应用程序中使用它。
new_notifications = [notif for notif in notifications if not notif.seen]
# do the update stuff
pass
# later on
for notif in notifications:
if notif in new_notifications:
# This one is new, do some stuff
pass
else:
# We already saw this notification, do some other stuff
pass
如果您需要更好的性能,请将 id 存储在字典中并检查:
new_notifications = dict([(notif.id, None) for notif in notifications if not notif.seen])
if notif.id in new_notifications:
pass
最后一个解决方案是像这样在通知上设置一个临时属性(可能以更正式的方式使用类方法或其他方式):
for notif in notifications:
notif.fresh = not notif.seen
那么你的代码依赖于新设置并使用它
【讨论】:
以上是关于停止 SQLAlchemy 更新已从数据库中提取的行的主要内容,如果未能解决你的问题,请参考以下文章