【问题标题】:Stop SQLAlchemy from updating rows that have already been pulled from the database停止 SQLAlchemy 更新已从数据库中提取的行
【发布时间】: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)

但不幸的是,它没有。

我该如何解决这个问题?

【问题讨论】:

    标签: python orm sqlalchemy


    【解决方案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
      

      那么你的代码依赖于新设置并使用它

      【讨论】:

        猜你喜欢
        • 2013-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多