TheShooter89/tgc-data-inspector

`use_session` decorator injecting session object and properly closing session

Opened this issue · 0 comments

Short Summary

use_session decorator injecting session object and properly closing session

Impact/Urgency

medium/high urgency

Full Description & Acceptance Criteria

ConnectionManager class provides use_session decorator to inject current session into external functions and properly handle Session cleanup, rollback and closing

Related Items & Feedback

📣 ConnectionManager instance holds current Session for shared use among different parts of the application and provides use_session decorator to easily use the session for query functions

  • use_session decorator method

Follow-up & Follows-from


scoped_session factory

from my_web_framework import get_current_request, on_request_end
from sqlalchemy.orm import scoped_session, sessionmaker

Session = scoped_session(sessionmaker(bind=some_engine), scopefunc=get_current_request)

Session API official docs

Session = sessionmaker(engine)

with Session.begin() as session:
    session.add(some_object)
    session.add(some_other_object)
# commits transaction, closes session

⚠️ scoped_session use with context manager with, Session Factory return type and scoped session strategy - reference github issue

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base, scoped_session, sessionmaker


Base = declarative_base()


class Test(Base):
    __tablename__ = 'test'
    id = Column(Integer, primary_key=True, unique=True, autoincrement=True)
    value = Column(String)


engine = create_engine("sqlite://", future=True)
Base.metadata.create_all(engine)

Session = scoped_session(sessionmaker(bind=engine, future=True))
# Session = sessionmaker(bind=engine, future=True)

with Session.begin() as session:
    session.add(Test(value="foo"))

# with Session() as session:
#     with session.begin():
#         session.add(Test(value="foo"))

Error

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
AttributeError: 'SessionTransaction' object has no attribute 'add'

Workaround
Replace:

with Session.begin() as session:

with:

with Session() as session:
    with session.begin():

refresher on python decorators:

import functools

def repeat(num_times):
    def decorator_repeat(func):
        @functools.wraps(func)
        def wrapper_repeat(*args, **kwargs):
            for _ in range(num_times):
                value = func(*args, **kwargs)
            return value
        return wrapper_repeat
    return decorator_repeat

accpeting both none and keyworded props (see here and here)

def repeat(_func=None, *, num_times=2):
    def decorator_repeat(func):
        @functools.wraps(func)
        def wrapper_repeat(*args, **kwargs):
            for _ in range(num_times):
                value = func(*args, **kwargs)
            return value
        return wrapper_repeat

    if _func is None:
        return decorator_repeat
    else:
        return decorator_repeat(_func)

Test Cases

none

Technical Notes

none


Guidelines Reference

use emoji-labeled quote blocks for important sections

⚠️ use this for dangerous/critical info sections

use this for sections about critical errors to avoid

📣 use this to mark important (but not dangerous/critical) points or reminders