【问题标题】:Overwrite postgresql onupdate with sqlalchemy用 sqlalchemy 覆盖 postgresql onupdate
【发布时间】:2019-07-27 18:11:19
【问题描述】:

原来的问题 我在我们的项目中使用sqlalchemy。我像这样为我的模型注册了几个事件监听器。

@event.listens_for(Post, 'after_update')
@event.listens_for(Post, 'after_insert')

我在代码的其他地方更新了模型的view_counter 属性。

post.view_counter += 1
DBSession.flush()

现在,由于 view_counter 不是我认为的内容更新,我想在 sqlalchemy 中禁止针对此特定更新触发 after_update 事件。有没有办法通过 ORM 做到这一点,或者是完全绕过 ORM 进行原始 SQL 更新的唯一方法?

编辑 经过一番摸索,我意识到还有另一个问题,该属性是由Postgresql 自己设置的

date_last_updated = Column(SA_DateTime, default=DateTime.now, onupdate=DateTime.now, nullable=False, index=True)

问题
所以问题是,如何在不触发 Postgresql 更新的情况下更新 sqlalchemy 模型。

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案1】:

    如果您能够对修饰函数进行更改,应该可以使用passed arguments 来确定哪些字段被修改,尽管通过一点a workaround。恐怕我还不能测试这个,但我希望它会有所帮助!

    @event.listens_for(Post, 'after_update', raw=True)
    @event.listens_for(Post, 'after_insert', raw=True)
    def myfunc(mapper, connection, target):
        # Values have been modified
        if target.session.is_modified(target, include_collections=False):
            # view_counter is the only modified value, the hook can be aborted
            if set(target.dict.keys()) - target.unmodified == {'view_counter'}:
                return
        <...the rest of the function...>
    

    【讨论】:

    • 谢谢,这确实解决了原来的问题,但我发现了另一个问题,我已经更新了问题。
    • 您可以将onupdate=DateTime.now 替换为onupdate=myupdatefunc 并使用docs.sqlalchemy.org/en/13/core/… 定义您自己的上下文感知更新函数
    • 另一种选择是将 updated_at 值显式设置为它已有的值,触发字段的“更新”应该意味着 onupdate 子句不被执行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 2018-10-06
    • 2020-11-22
    • 2015-11-17
    相关资源
    最近更新 更多