2021-08-17 17:00:34 +08:00
|
|
|
|
|
|
|
from typing import Iterator
|
|
|
|
|
|
|
|
from contextlib2 import contextmanager
|
|
|
|
from sqlalchemy import create_engine
|
|
|
|
from sqlalchemy.exc import SQLAlchemyError
|
|
|
|
from sqlalchemy.orm import Session, sessionmaker
|
|
|
|
from sqlalchemy.pool import NullPool
|
2023-12-11 13:23:35 +08:00
|
|
|
import logging
|
2021-08-17 17:00:34 +08:00
|
|
|
from myapp import app, db
|
|
|
|
|
|
|
|
|
|
|
|
# Null pool is used for the celery workers due process forking side effects.
|
|
|
|
@contextmanager
|
|
|
|
def session_scope(nullpool: bool) -> Iterator[Session]:
|
|
|
|
"""Provide a transactional scope around a series of operations."""
|
|
|
|
database_uri = app.config["SQLALCHEMY_DATABASE_URI"]
|
|
|
|
if nullpool:
|
|
|
|
engine = create_engine(database_uri, poolclass=NullPool)
|
|
|
|
session_class = sessionmaker()
|
|
|
|
session_class.configure(bind=engine)
|
|
|
|
session = session_class()
|
|
|
|
else:
|
|
|
|
session = db.session()
|
|
|
|
session.commit() # HACK
|
|
|
|
|
|
|
|
try:
|
|
|
|
yield session
|
|
|
|
session.commit()
|
|
|
|
except SQLAlchemyError as ex:
|
|
|
|
session.rollback()
|
2023-12-11 13:23:35 +08:00
|
|
|
logging.exception(ex)
|
2021-08-17 17:00:34 +08:00
|
|
|
raise
|
|
|
|
finally:
|
|
|
|
session.close()
|