首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对于SQLAlchemy中的特定更新查询,跳过onupdate定义的默认值

对于SQLAlchemy中的特定更新查询,跳过onupdate定义的默认值
EN

Stack Overflow用户
提问于 2021-10-19 05:31:04
回答 2查看 494关注 0票数 4

如果我有一个帖子列表,其中包含createdupdated日期,并附带默认的onupdate回调。

有时,为了inappropriate reports或类似的操作,我需要标记这个帖子。我不希望修改createdupdated日期。

如何在创建onupdate操作时跳过定义的update

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-20 11:43:28

SQLAlchemy将应用默认的什么时候

没有为该列的INSERT或UPDATE语句提供任何值。

然而,显而易见的解决办法--将列显式设置为其当前值--将无法工作,因为会话检查是否实际更改了值,如果没有更改,则不会传递值。以下是两种可能的解决方案,假设SQLAlchemy 1.4+和此模型:

代码语言:javascript
运行
复制
class Post(db.Model):
    flag = db.Column(db.Boolean, default=False)
    last_updated = db.Column(db.DateTime, default=some_func, onupdate=some_func)

使用事件侦听器

添加一个检测标志列何时被修改的更新侦听器之前,并将时间戳列作为已修改的标记,即使其值不变。这将使SQLAlchemy将当前值添加到更新中,因此不会调用onupdate函数。

代码语言:javascript
运行
复制
import sqlalchemy as sa
...
@sa.event.listens_for(Post, 'before_update')
def receive_before_update(mapper, connection, target):
    insp = sa.inspect(target)
    flag_changed, _, _ = insp.attrs.flag.history
    if flag_changed:
        orm.attributes.flag_modified(target, 'last_updated')

使用SQLAlchemy核心而不是ORM

SQLAlchemy核心不需要会话,因此可以将当前的时间戳值传递给更新,以避免触发onupdate函数。ORM将不知道以这种方式所做的任何更改,因此,如果在会话受影响对象的上下文中进行更改,则应该刷新或过期对象。这是一个“快速和肮脏”的解决方案,但如果标记发生在正常应用程序流之外,则可能足够好。

代码语言:javascript
运行
复制
with db.engine.begin() as conn:
    posts = Post.__table__
    update = sa.update(posts).where(...).values(flag=True, last_updated=posts.c.last_updated)
    conn.execute(update)
票数 5
EN

Stack Overflow用户

发布于 2022-11-09 12:41:25

您可以简单地分配带有SQLAlchemy核心级别列对象的列来发出SQL,比如'UPDATE post set created=post.created,updated=post.update‘。

代码语言:javascript
运行
复制
class Post(Base):
  id=Column(Integer,primary_key=True)
  name=Column(String)
  created=Column(DateTime,onupdate=func.now())
  updated=Column(DateTime,onupdate=func.now())

post=session.query(Post).first()
post.name='updated post'
post.created= Post.__table__.c.created
post.updated= Post.__table__.c.updated
session.commit()

已发送的SQL:

代码语言:javascript
运行
复制
UPDATE post SET name='updated post', created=post.created, updated=post.updated WHERE post.id=1;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69625550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档