Asumir tabla tiene tres columnas: username
, password
y no_of_logins
.
Cuando el usuario intenta iniciar sesión, se verifica si hay una entrada con una consulta como
user = User.query.filter_by(username=form.username.data).first()
Si la contraseña coincide, él continúa. Lo que me gustaría hacer es contar cuántas veces el usuario inició sesión. Por lo tanto, cada vez que inicie sesión con éxito, me gustaría incrementar el no_of_logins
campo y almacenarlo de nuevo en la tabla de usuarios. No estoy seguro de cómo ejecutar la consulta de actualización con SqlAlchemy.
python
sqlalchemy
flask-sqlalchemy
webminal.org
fuente
fuente
user.no_of_logins += 1
puede crear condiciones de carrera. En lugar de usaruser.no_of_logins = user.no_of_logins + 1
. Traducido a sql la forma correcta este último se convierte en:SET no_of_logins = no_of_logins + 1
.user.no_of_logins = User.no_of_logins + 1
, o en otras palabras, usa el atributo instrumentado del modelo para producir una expresión SQL. Como es, su comentario muestra 2 formas de producir la misma condición de carrera.Hay varias formas de
UPDATE
usarsqlalchemy
fuente
setattr(query_result, key, value)
algunas actualizaciones en Flask SQLAlchemy seguido de un commit. ¿Alguna razón para descontar este patrón?setattr(query_result, key, value)
, que es exactamente equivalente a escribirquery_result.key = value
Ejemplos para aclarar la cuestión importante en los comentarios de las respuestas aceptadas
No lo entendí hasta que jugué con él, así que pensé que habría otros que también estarían confundidos. Digamos que está trabajando en el usuario cuyo
id == 6
yno_of_logins == 30
cuándo comienza.El punto
Al hacer referencia a la clase en lugar de la instancia, puede hacer que SQLAlchemy sea más inteligente sobre el incremento, haciendo que suceda en el lado de la base de datos en lugar del lado de Python. Es mejor hacerlo dentro de la base de datos, ya que es menos vulnerable a la corrupción de datos (por ejemplo, dos clientes intentan aumentar al mismo tiempo con un resultado neto de solo un incremento en lugar de dos). Supongo que es posible hacer el incremento en Python si establece bloqueos o aumenta el nivel de aislamiento, pero ¿por qué molestarse si no tiene que hacerlo?
Una advertencia
Si va a incrementar dos veces a través de un código que produce SQL como
SET no_of_logins = no_of_logins + 1
, entonces necesitará confirmar o al menos vaciar entre incrementos, de lo contrario solo obtendrá un incremento en total:fuente
Con la ayuda de la
user=User.query.filter_by(username=form.username.data).first()
declaración obtendrá el usuario especificado enuser
variable.Ahora puede cambiar el valor de la nueva variable de objeto como
user.no_of_logins += 1
y guardar los cambios con elsession
método de confirmación.fuente
Escribí telegram bot y tengo algún problema con las filas de actualización. Use este ejemplo, si tiene Modelo
¿Por qué usar
db.session.flush()
? Es por eso que >>> SQLAlchemy: ¿Cuál es la diferencia entre flush () y commit ()?fuente
flush()
siempre se llama como parte de una llamada acommit()
"