postgresql SqlAlchemy,更新后返回以前的数据

q5lcpyga  于 2023-03-29  发布在  PostgreSQL
关注(0)|答案(1)|浏览(277)

有必要在SQLAlchemy对象上编写一个查询,以在更新后返回以前的值。Postgresql
下表可用:

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True, server_default=text("nextval('\"public\".users_id_seq'::regclass)"))
    last_name = Column(String(255), nullable=False)
    first_name = Column(String(255), nullable=False)
    email = Column(String(255), nullable=False, unique=True)

我需要在更新后返回以前的数据。

update
    users x
        set
            email = 'example@example.com'
        from
            (
            select
                *
            from
                users
            where
                id = 1 for update) y
        where
            x.id = y.id
        returning 
            y.*

尝试写这样的东西是不成功的

old_user: User = aliased(User, name='old_user')

update_stmt = update(User) \
    .where(user_old.id == User.id) \
    .where(User.id == 1) \
    .values(email = "example@example.com") \
    .returning(old_user)

return session.execute(update_stmt)

发生错误sqlalchemy.exc.NoSuchColumnError: Could not locate column in row for column 'old_user.id'
但是如果您尝试返回一个非别名对象,则会返回一个具有新值的对象。
此外,尝试返回(text(public.old_user.*))会导致错误NotImplementedError

kkbh8khc

kkbh8khc1#

你不能直接做你想做的事情。一旦更新,获取旧值的唯一方法是将其归档到另一个表,或者回滚更新。然而有一个解决方案(不一定是好的)。Postgres允许CTE包含DML。因此创建2个CTE,第一个检索旧数据,第二个进行更新,最后主查询检索第一个CTE:(参见demo

with old_row as 
     ( select email   
         from users 
        where id = 1
      ) 
   , new_row as 
     ( update users 
          set email = 'example@example.com'
        where id=1
     ) 
select * 
  from old_row;

对不起,我不知道你的晦涩语言(SQLAlchemy),所以我把它的翻译留给你。

相关问题