阻止SQLAlchemy更新已从数据库中提取的行

时间:2013-07-02 21:11:44

标签: python orm sqlalchemy

我正在为网站创建一个简单的通知系统。用户的通知从数据库中提取,标记为已显示(如果尚未显示),然后显示给用户。看不见的那些以粗体显示。这是我的一些代码:

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}}

但不幸的是,它没有。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我认为在这里做任何过于棘手的事情都不值得,比如打破同步或从会话中删除对象。在这种情况下,最好保存预先看不到的通知列表,然后在应用程序中使用它。

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

然后你的代码依赖于新设置并使用它

答案 1 :(得分:0)

synchronize_session = False正在执行,但您还需要在查看通知之前不提交,或者在会话中转换expire_on_commit = False。在提交后首次访问时,通常会从DB刷新该对象。