266 votes

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

Supposons que le tableau comporte trois colonnes : username , password y no_of_logins .

Lorsque l'utilisateur essaie de se connecter, on vérifie s'il y a une entrée avec une requête du type

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

Si le mot de passe correspond, il continue. Ce que je voudrais 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 la variable no_of_logins et le renvoie dans la table des utilisateurs. Je ne sais pas comment exécuter la requête de mise à jour avec SqlAlchemy.

560voto

Niima Points 11

Il existe plusieurs façons de UPDATE en utilisant sqlalchemy

1) user.no_of_logins += 1
   session.commit()

2) session.query(User).\
       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()

206voto

Denis Points 1919
user.no_of_logins += 1
session.commit()

68voto

MarredCheese Points 2206

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

Je ne l'ai pas compris avant d'avoir joué avec, et je me suis dit que d'autres personnes seraient également déroutées. Disons que vous travaillez sur l'utilisateur dont id == 6 et dont no_of_logins == 30 quand vous commencez.

# 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 faisant référence à la classe plutôt qu'à l'instance, vous pouvez faire en sorte que SQLAlchemy soit plus intelligent en matière d'incrémentation, en faisant en sorte que cela se passe du côté de la base de données plutôt que du côté de Python. Il est préférable de le faire dans la base de données car il 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 seul incrément au lieu de deux). Je suppose qu'il est possible d'effectuer l'incrémentation en Python si l'on pose des verrous ou si l'on augmente le niveau d'isolation, mais à quoi bon si ce n'est pas nécessaire ?

Un avertissement

Si vous allez incrémenter deux fois via un code qui produit du SQL comme SET no_of_logins = no_of_logins + 1 vous devrez alors vous engager ou au moins faire une purge entre les incréments, sinon vous n'obtiendrez qu'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

7voto

Andrew Lutsyuk Points 87

J'ai écrit un bot telegram, et j'ai un problème avec les lignes de mise à jour. Utilisez cet exemple, si vous avez le 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 pour ça que >>> SQLAlchemy : Quelle est la différence entre flush() et commit() ?

6voto

Lafada Points 6393

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

Maintenant, vous pouvez modifier la valeur de la nouvelle variable objet comme suit user.no_of_logins += 1 et enregistrez les modifications avec le bouton session La méthode d'engagement de l'entreprise.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X