engine은 일반적으로 sqlalchemy.engine.create_engine 함수에 의해 생성되는, SQLAlchemy에서 사용되는 lowest level의 객체다. engine은 어플리케이션이 데이터베이스와 통신할 때마다 사용할 수 있는 connection pool을 유지한다. 쿼리를 위해 사용하는 engine.executeengine.connect(close_with_result=True)를 수행해 Connection 객체를 얻고, conn.execute를 호출하는 편리한 메소드다. ORM을 사용하지 않아서, sqlalchemy.text 함수로 객체에 바인딩되지 않은 straight SQL 쿼리를 수행하는 경우 이처럼 engine과 connection을 사용하는 것이 적절한 방법이다.

어플리케이션이 SQLAlchemy ORM을 사용한다면, 객체에 바인딩된 쿼리를 위해서 Session 객체를 사용해야 한다. 이는 session.add(), session.rollback(), session.commit(), session.close()를 통해 트랜잭션을 단일 작업 단위로 관리하기 좋고, 이러한 특징을 통해 Python의 Context Manager 패턴을 사용하기에도 좋다.

session을 생성해 yield하고, 정상적인 경우 commit, 오류가 발생하면 rollback, 어느 상황이든 close하도록 만든다. 쿼리가 필요한 부분을 with-as 블럭으로 감싸기만 하면, global한 트랜잭션 관리는 context manager가 모두 수행해 준다. SQLAlchemy 문서에서는 위와 같은 구현을 scoped session이라고 이야기하고 있다. 따라서 raw string SQL을 사용하는 경우 engine이나 connection, ORM을 사용하는 경우 session과 scoped session 패턴을 사용하는 것이 적합하다고 생각한다. session 객체에서도 물론 execute 메소드가 지원되기 때문에, 어플리케이션 전체에 걸쳐 그냥 session만 사용하는 practice도 꽤 있었던 것 같다.

앞으로 블로그의 SQLAlchemy 카테고리에 올라올 포스트들의 예제는, scoped session이 적용되어 있다(session_scope 함수가 이미 존재한다)는 것을 가정하고 작성될 예정이다.

+ Recent posts