代码之家  ›  专栏  ›  技术社区  ›  Metadata

如何在SQLAlchemyPython中使用模型类对象更新表中的行?

  •  0
  • Metadata  · 技术社区  · 4 年前

    假设表有三列: username , password no_of_logins .

    当用户尝试登录时,它会检查一个带有如下查询的条目

    user = User.query.filter_by(username=form.username.data).first()
    

    字段并将其存储回用户表。我不知道如何用SqlAlchemy运行更新查询。

    0 回复  |  直到 5 年前
        1
  •  157
  •   Denis    12 年前
    user.no_of_logins += 1
    session.commit()
    
        2
  •  394
  •   Spectral    7 年前

    UPDATE 使用 sqlalchemy

    1) user.no_of_logins += 1
       session.commit()
    
    2) session.query().\
           filter(User.username == form.username.data).\
           update({"no_of_logins": (User.no_of_logins +1)})
       session.commit()
    
    3) conn = engine.connect()
       stmt = User.update().\
           values(no_of_logins=(User.no_of_logins + 1)).\
           where(User.username == form.username.data)
       conn.execute(stmt)
    
    4) setattr(user, 'no_of_logins', user.no_of_logins+1)
       session.commit()
    
        3
  •  26
  •   MarredCheese Lionia Vasilev    5 年前

    我不明白,直到我自己玩了它,所以我想会有其他人也感到困惑。假设您正在处理 id == 6 no_of_logins == 30 当你开始的时候。

    # 1 (bad)
    user.no_of_logins += 1
    # result: UPDATE user SET no_of_logins = 31 WHERE user.id = 6
    
    # 2 (bad)
    user.no_of_logins = user.no_of_logins + 1
    # result: UPDATE user SET no_of_logins = 31 WHERE user.id = 6
    
    # 3 (bad)
    setattr(user, 'no_of_logins', user.no_of_logins + 1)
    # result: UPDATE user SET no_of_logins = 31 WHERE user.id = 6
    
    # 4 (ok)
    user.no_of_logins = User.no_of_logins + 1
    # result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6
    
    # 5 (ok)
    setattr(user, 'no_of_logins', User.no_of_logins + 1)
    # result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6
    

    重点

    通过引用类而不是实例,您可以使SQLAlchemy在增量方面更聪明,使增量发生在数据库端而不是Python端。在数据库中这样做会更好,因为它不太容易受到数据损坏的影响(例如,两个客户机试图同时递增,而净结果只有一个递增而不是两个递增)。如果设置了锁或提高了隔离级别,我假设可以在Python中执行增量操作,但是如果不必这样做,为什么还要麻烦呢?

    如果要通过生成类似SQL的 SET no_of_logins = no_of_logins + 1 ,则需要提交或至少在增量之间刷新,否则总共只能得到一个增量:

    # 6 (bad)
    user.no_of_logins = User.no_of_logins + 1
    user.no_of_logins = User.no_of_logins + 1
    session.commit()
    # result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6
    
    # 7 (ok)
    user.no_of_logins = User.no_of_logins + 1
    session.flush()
    # result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6
    user.no_of_logins = User.no_of_logins + 1
    session.commit()
    # result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6
    
        4
  •  6
  •   Nilesh    12 年前

    在…的帮助下 user=User.query.filter_by(username=form.username.data).first() 语句中指定的用户 user 变量。

    现在可以更改新对象变量的值 user.no_of_logins += 1 session 的提交方法。

        5
  •  5
  •   MarredCheese Lionia Vasilev    5 年前

    我编写了telegrambot,在更新行时遇到了一些问题。 使用这个例子,如果你有一个模型

    def update_state(chat_id, state):
        try:
            value = Users.query.filter(Users.chat_id == str(chat_id)).first()
            value.state = str(state)
            db.session.flush()
            db.session.commit()
            #db.session.close()
        except:
            print('Error in def update_state')
    

    为什么使用 db.session.flush() ? 这就是为什么>> SQLAlchemy: What's the difference between flush() and commit()?