2019.05.23 - SQLAlchemy 의 객체 상태 관리 (expire, refresh, flush, commit) 에 관한 이해

SQLAlchemy에서 모델을 다루는 stage에 대해 알아보았다.

  1. Expire
    • I've made some changes to an object and don't need it immediately but don't want any subsequent methods to use stale values.
    • db.session.expire(Model)
  2. Refresh
    • I've made some changes to an object and need its updated values immediately.
    • Costs extra database call as it expires and reads from database immediately.

  3. Flush
    • Push changes from memory to your database's transaction buffer. No database statements are issued yet.
    • If Session has autocommit: False, must still call commit() to persist the changes or rollback() to discard changes.
    • If Session has autocommit: True and you are not explicitly in a transaction, commit() will be automatically called.
  4. Commit
    • Persist changes in your database's transaction buffer to the database. Database statements are issued.
    • Automatically expires objects.
  5. Merge
    • Used when you may have more than 1 in-memory objects which map to the same database record with some key.
    • Merging causes the in-memory objects to be synchronised with each other, does not necessarily persist to the database.


1. expire

- 객체에 실컷 변형을 가했으나 폐기처분을 하는 경우
- User Model을 DB로부터 가지고 오고 property들을 신나게 바꿨는데 조건에 부합하지 않아서 현재 상태를 폐기하고 싶을 때 사용한다.
- 프로퍼티 변형이 많이 이루어졌지만 유효성 검증이 되지 않았을 경우 실행하면 좋을 것 같다.
- 하지만 rollback이 좀 더 범용적으로 쓰이지 않을까 싶다.
- 만약 여러 row들에 업데이트가 가해졌고 다른 row들은 모두 유효성이 검증되었지만, 마지막 row만 실패했을 경우에 이를 사용하면 좋을 것 같다. 커밋을 할 경우 마지막 row만 폐기되고 나머지 row들은 업데이트 될 것이니까.

- db.session.expire(user)


2. Refresh

- 객체에 실컷 변형을 가했는데 객체에 최신 상태가 필요할 때.
- DB로부터 받아 온 모델의 프로퍼티를 신나게 바꿨지만, 다른 곳에서 커밋이 일어나서 내가 사용하는 모델이 오래 된 모델일 경우가 있을 것이다. (여러 쓰레드에서 같은 객체를 본다면 그러할 수 있을 듯)
- 이 상태에서 commit이 되면 결과적으로 오래 된 객체 + 내 업데이트 사항만 반영이 될 확률이 높다.
- 이를 방지하기 위해 Refresh를 사용할 수 있고 이는 현재시점에서 DB에서 Read를 해서 최신상태의 객체를 불러온다.
- DB에서 새로 Read 하기 때문에 불필요한 비용이 있을 수 있다.

- db.session.refresh(user)


3. Flush

- DB에 반영할 사항들을 모아놓는 곳을 DB Transaction buffer라 한다.
- Flush는 DB의 버퍼에 변경 된 사항들을 반영하는 것을 의미한다. (DB에 반영이 아니다. DB 버퍼에 반영이다)
- flush는 session의 옵션에 autocommit=True인지 False 인지에 따라 행위가 달라진다.
- 만약 autocommit이 설정되어 있으면 flush를 할 경우에 자동으로 commit 까지 된다.
- 그렇지 않은 경우엔 DB에 올릴 버퍼에만 반영사항을 두고 나중에 매뉴얼하게 commit이 불리면 그 때 DB에 반영이 된다.
- flush를 했다면 commit을 하지 않더라도 파이썬 내에서 이제 그 row(혹은 객체)는 변경한 속성을 유지한다.


4. Commit

- 결재 상신 완료.
- 버퍼에 올라있던 사항들을 모두 DB에 반영한다.
- Commit 전에만 Rollback을 하면 버퍼가 모두 날아간다.

Merge는 잘 안 쓰일 것으로 예상되기에 생략.

댓글

이 블로그의 인기 게시물

로컬 Tomcat 서버 실행속도 개선

2020.02.17 Python의 multiprocessing 중 Pool.map(), chunksize에 관한 내용