Python & SQAlchemy session_scope

우야·2021년 5월 13일
0

파이썬과 함께 비동기 처리를 위한 scope_session사용 방법

Python 비동기 처리와 SQAlchemy session_scope을 사용하는 비동기 처리가 문제가 될수 있다.

이유는

  • scoped_session
    - 단일 DB Connection으로 세션을 만들수 있는 메커니즘이고,
    • session은 스레드 단위로 생성된다.
  • 파이썬의 비동기 방식은 코루틴(단일 스레드)
    - 여러 요청에 대해서 EventLoop가 요청을 받아서 동시에 처리할 수 있도록 한다.
    - 코루틴은 단일 스레드로 동작함 (Node.js와 같음)

이런 이유로, 파이썬에 동시 요청이 들어왔을때, 동일한 db session을 사용하게된다.

  • 동일 session 사용시 문제점

    • 해당 session 객체에 Exception이 발생하게 되면, 다른 요청에서 사용한 session 객체에서도 똑같은 문제가 발생하여, 오류 전파의 원인 발생

    해결 방법
    각 요청마다 새로운 session을 생성해서, 동시 요청시 동일 session을 공유하지 않게 하여, 트랜잭션 오류등 다른 요청에 영향을 주지 않게 해야한다.

  1. scoped_session을 사용하지 않고, session을 생성 하는 방법
    • db conection/close를 Application 시작,종료시 처리 포함
from fastapi import Depends
from sqlachemy import create_engine
from sqlachemy.engine import Engine
from sqlachemy.ext.declarative import declarative_base
from sqlachemy.orm import Session
from typing import AsyncIterable, Optional

_db_connection: Engine = Optional[Engine]
engine_uri = 'postgresql://...'

def on_startup():
    global _db_connection
    _db_connection = create_engine(engine_uri)
    
def on_shutdown():
   global _db_connection
   if _db_connection:
       _db_connection.dispose()
      
async def get_db_connection() -> Engine:
    assert _db_connection is not None
    return _db_connection

async def get_deb_session(db_conn: Engine = Depends(get_db_connection)) -> AsyncIterable[Session]:
	ss = Session(bind=engine)
    try:
    	yield ss
    finally:
        ss.close()
profile
Fullstack developer

0개의 댓글