web-dev-qa-db-fra.com

Comment mettre à jour l'entrée de ligne SQLAlchemy?

Supposer table a trois colonnes: username, password et no_of_logins.

Lorsque l'utilisateur essaie de se connecter, il vérifie l'entrée avec une requête comme

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

Si le mot de passe correspond, il continue. Ce que j'aimerais faire, c'est compter combien de fois l'utilisateur s'est connecté. Ainsi, chaque fois qu'il se connecte avec succès, j'aimerais incrémenter le champ no_of_logins et le stocker dans la table des utilisateurs. Je ne sais pas comment exécuter la requête de mise à jour avec SqlAlchemy.

93
webminal.org
user.no_of_logins += 1
session.commit()
90
Denis

Il y a plusieurs façons de UPDATE d'utiliser 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()
246
Nima Soroush

Avec l'aide de l'instruction user=User.query.filter_by(username=form.username.data).first(), vous obtiendrez l'utilisateur spécifié dans la variable user

Vous pouvez maintenant modifier la valeur de la nouvelle variable d'objet telle que user.no_of_logins += 1 et enregistrer les modifications à l'aide de la méthode commit de session.

3
Nilesh

Exemples pour clarifier la question importante dans les commentaires de réponse acceptés

Je n'y comprenais rien avant de jouer moi-même. J'ai donc pensé qu'il y en aurait d'autres qui seraient également désorientés. Supposons que vous travaillez sur l'utilisateur dont id == 6 et dont no_of_logins == 30 lorsque vous démarrez.

# 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

Le point

En référençant la classe à la place de l'instance, vous pouvez obtenir que SQLAlchemy soit plus intelligente en ce qui concerne l'incrémentation, ce qui se produit du côté de la base de données au lieu du côté Python. Il est préférable de le faire dans la base de données car elle est moins vulnérable à la corruption des données (par exemple, deux clients tentent d’incrémenter en même temps avec un résultat net d’un incrément au lieu de deux). Je suppose qu'il est possible de faire l'incrémentation dans Python si vous définissez des verrous ou si vous augmentez le niveau d'isolation, mais pourquoi ne pas vous déranger si vous n'avez pas à le faire?

Une mise en garde

Si vous envisagez d'incrémenter deux fois via un code produisant du code SQL tel que SET no_of_logins = no_of_logins + 1, vous devrez alors valider ou au moins effacer entre les incréments, sinon vous obtiendrez un seul incrément au total:

# 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
0
MarredCheese

J'ai écrit le télégramme bot et quelques problèmes avec les lignes de mise à jour. Utilisez cet exemple, si vous avez un modèle

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')

Pourquoi utiliser db.session.flush ()? C'est pourquoi >>> SQLAlchemy: Quelle est la différence entre flush () et commit ()?

0
Andrew Lutsyuk