-
[python] sqlalchemy > sessionmaker > autocommit, autoflush에 대해공부 이야기 2024. 2. 26. 09:23
단 두 줄로 데이터베이스와 커넥션(세션)을 맺을 수 있는 sqlalchemy 코드를 보고 문득 떠올랐다.
sessionmaker() 메소드를 구성하기 위해 어떤 항목들이 숨겨져있을까.
그 중에서 이번에 확인할 내용은 autocommit, autoflush이다.
(1/4) Autoflush = True, Autocommit = True
-> begin(), commit() 메소드를 직접 호출해줘야 INSERT 쿼리문(트랜잭션)이 BEGIN ~ COMMIT 으로 감싸져서 처리됨을 확인할 수 있음 -> begin() 메소드를 호출하지 않고 commit() 메소드를 호출한 경우, No Transaction is begun 에러 발생 -> flush() 메소드를 호출해주면 begin(), commit() 메소드를 호출하지 않아도 자동으로 COMMIT이 발생 (2/4) Autoflush = False, Autocommit = True
-> begin() 메소드를 호출하지 않으면 No transation is begun 에러가 발생 session 객체 값이 변경이 되어도 UPDATE 쿼리가 발생하지 않고 DB 변경도 없음 -> flush()를 호출해준 경우 자동으로 COMMIT 및 DB update 처리 (3/4) Autoflush = True, Autocommit = False
-> begin() 메소드를 호출하지 않아도 No transaction is begun 에러가 발생하지 않고 INSERT 쿼리가 실행 + 특이한 점은 자동으로 SELECT 조회 쿼리를 실행하는데 마지막에는 ROLLBACK이 발생 자동으로 SELECT 조회 쿼리를 실행하는 이유는 return todo
-> UPDATE 쿼리도 위와 동일하게 처리 -> flush() 메소드를 호출해도 COMMIT이 발생하지 않음 ROLLBACK 확인 INSERT 쿼리도 마찬가지로 DB로 쿼리는 실행이 되지만 ROLLBACK -> commt() 메소드를 호출해야 정상적으로 DB INSERT 처리 완료(COMMIT) -> flush() 메소드를 호출하지 않고 commit() 메소드를 호출해도 위와 동일하게 동작함(COMMIT) -> UPDATE 쿼리도 동일 (4/4) Autoflush = False , Autocommit = False
-> flush() 메소드만 호출한 경우 DB ROLLBACK -> commit() 메소드까지 호출해야 DB INSERT가 정상적으로 실행(COMMIT 됐다는 뜻ㅎ) -> flush() 메소드를 호출하지 않고 commit() 메소드만 호출했을 때 DB COMMIT이 발생하는 것으로 보아, "commit이 발생하면 flush가 자동으로 발생하는 사실을 알 수 있음" -> begin() ~ commit() 메소드 안에 INSERT 쿼리와 SELECT 쿼리를 추가하면 하나의 트랜잭션 단위로 처리함 SELECT 쿼리를 호출하는 메소드를 INSERT 쿼리를 호출하는 메소드 뒤에 추가했음에도 불구하고 SELECT 쿼리가 먼저 호출되는걸 확인할 수 있음
-> todos 테이블의 PK는 id임, WHERE 절에 NULL이 들어가 있음 Mysql DB에서 Auto Increment 방식으로 값을 할당받는 PK인 경우, 입력값으로 PK를 넘기지 않을 경우 NULL을 조회함
물론 PK에는 NULL이 들어갈 수 없기 때문에 값이 조회되는 경우는 없음
하지만 개발 의도가 INSERT 했던 row를 조회하기 위함이라면 위와 같은 방식을 사용하면 안됨
이 경우 refresh() 메소드를 사용해야 함 (근데 sqlalchemy에서 자동으로 조회함)
-> 한편, UPDATE 쿼리의 경우 begin() 메소드를 호출하면 already begun 에러가 발생함 -> UPDATE 쿼리의 경우 begin() ~ commit() 메소드 안에 SELECT 쿼리와 함께 추가할 수 없음. 따라서 호출 순서대로 쿼리 실행 번외)
테스트를 수행하면서 auto increment 칼럼인 id가 중간에 건너뛰어진걸 볼 수 있다.
이는 flush()만 호출하고 commit()을 호출하지 않았을 때 ROLLBACK된 상황에서 발생한 것으로
ROLLBACK이 발생한 경우에도 id 값은 재사용하지 않는 MySQL 특성이다.
'공부 이야기' 카테고리의 다른 글