Pergunta

Suponha que a tabela tenha três colunas: username, password e no_of_logins.

Quando o usuário tenta fazer login, é verificada uma entrada com uma consulta como

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

Se a senha corresponder, ele prossegue.O que eu gostaria de fazer é contar quantas vezes o usuário efetuou login.Assim, sempre que ele fizer login com sucesso, gostaria de incrementar o no_of_logins campo e armazene-o de volta na tabela do usuário.Não sei como executar a consulta de atualização com o SqlAlchemy.

Foi útil?

Solução

user.no_of_logins += 1
session.commit()

Outras dicas

Existem várias maneiras de UPDATE usando 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()

Exemplos para esclarecer a questão importante nos comentários das respostas aceitas

Eu não entendi até que brinquei sozinho, então imaginei que haveria outras pessoas que também ficariam confusas.Digamos que você esteja trabalhando no usuário cujo id == 6 e cujo no_of_logins == 30 quando você começar.

# 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

O ponto

Ao referenciar a classe em vez da instância, você pode fazer com que o SQLAlchemy seja mais inteligente no incremento, fazendo com que isso aconteça no lado do banco de dados em vez do lado do Python.Fazer isso dentro do banco de dados é melhor, pois é menos vulnerável à corrupção de dados (por exemplo,dois clientes tentam incrementar ao mesmo tempo com um resultado líquido de apenas um incremento em vez de dois).Presumo que seja possível fazer o incremento em Python se você definir bloqueios ou aumentar o nível de isolamento, mas por que se preocupar se não é necessário?

Uma advertência

Se você for incrementar duas vezes por meio de código que produz SQL como SET no_of_logins = no_of_logins + 1, então você precisará confirmar ou pelo menos liberar entre os incrementos, ou então obterá apenas um incremento no 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

Com a ajuda de user=User.query.filter_by(username=form.username.data).first() declaração você obterá o usuário especificado em user variável.

Agora você pode alterar o valor da nova variável de objeto como user.no_of_logins += 1 e salve as alterações com o sessionmétodo de confirmação.

Escrevi um bot de telegrama e tenho alguns problemas com as linhas de atualização.Use este exemplo, se você tiver Model

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

Por que usar db.session.flush()?É por isso >>> SQLAlquimia:Qual é a diferença entre flush() e commit()?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top