[python] SQLAlchemy 행 항목을 업데이트하는 방법?

가정의 표는 세 개의 열이 있습니다 username, password하고 no_of_logins.

사용자가 로그인을 시도하면 다음과 같은 쿼리가있는 항목을 확인합니다.

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

암호가 일치하면 더 진행합니다. 내가하고 싶은 것은 사용자가 로그인 한 횟수를 세는 것입니다. 따라서 그가 성공적으로 로그인 할 때마다 no_of_logins필드를 늘리고 다시 사용자 테이블에 저장하고 싶습니다 . SqlAlchemy로 업데이트 쿼리를 실행하는 방법을 잘 모르겠습니다.



답변

user.no_of_logins += 1
session.commit()


답변

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


답변

허용 된 답변의 주석에서 중요한 문제를 명확히하는 예

나는 그것을 가지고 놀 때까지 그것을 이해하지 못했기 때문에 혼란스러워하는 다른 사람들도있을 것이라고 생각했습니다. 시작한 사람 id == 6no_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가 증가하는 것에 대해 더 똑똑 해져서 파이썬 쪽이 아닌 데이터베이스 쪽에서 발생할 수 있습니다. 데이터 손상에 덜 취약하기 때문에 데이터베이스 내에서 수행하는 것이 좋습니다 (예 : 두 클라이언트가 동시에 두 개가 아닌 한 번만 순 결과로 증가하려고 시도 함). 잠금을 설정하거나 격리 수준을 높이면 파이썬에서 증분을 수행 할 수 있다고 가정하지만 필요하지 않은 이유는 무엇입니까?

경고

SQL과 같은 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


답변

user=User.query.filter_by(username=form.username.data).first()명령문 의 도움으로 지정된 사용자를 user변수로 가져올 수 있습니다.

이제 새 객체 변수의 값을 변경하고 의 commit 메소드로 user.no_of_logins += 1변경 사항을 저장할 수 session있습니다.


답변

전보 봇을 작성하고 업데이트 행에 문제가 있습니다. 모델이있는 경우이 예를 사용하십시오.

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 : flush ()와 commit ()의 차이점은 무엇입니까?


답변