Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sqlalchemy use scoped_session in Tornado
# -*- coding: utf-8 -*-
import store
from tools.tor import ThreadRequestContext
class BaseHandler(RequestHandler):
def prepare(self):
store.db()
def on_finish(self):
store.db.remove()
def _execute(self, transforms, *args, **kwargs):
global_data = {"request_id": id(self)}
with stack_context.StackContext(functools.partial(ThreadRequestContext, **global_data)):
return super(BaseHandler, self)._execute(transforms, *args, **kwargs)
# -*- coding: utf-8 -*-
from sqlalchemy import Column
from sqlalchemy.dialects.mysql import INTEGER, BIT, VARCHAR
from store import Base
from store import db
class User(Base):
__tablename__ = "user"
id = Column(INTEGER, primary_key=True, autoincrement=True)
username = Column(VARCHAR(20), nullable=False)
password = Column(VARCHAR(20), nullable=False)
is_delete = Column(BIT, default=0, nullable=False)
@classmethod
def get_all(cls):
return db.query(User).filter(User.is_delete == 0).all()
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
from config import Config
from tools.tor import get_current_request_id
engine = create_engine(Config.DB,
encoding='utf-8',
echo=Config.SQLALCHEMY_ECHO,
pool_recycle=600,
pool_size=20,
max_overflow=100)
db = scoped_session(sessionmaker(bind=engine,
autocommit=False,
autoflush=True,
expire_on_commit=False,
), scopefunc=get_current_request_id)
Base = declarative_base()
# -*- coding: utf-8 -*-
import threading
class Metaclass(type):
# property() doesn't work on classmethods,
# see http://stackoverflow.com/q/128573/1231454
@property
def data(cls):
if not hasattr(cls._state, 'data'):
return {}
return cls._state.data
class ThreadRequestContext(object, metaclass=Metaclass):
"""A context manager that saves some per-thread state globally.
Intended for use with Tornado's StackContext.
Provide arbitrary data as kwargs upon creation,
then use ThreadRequestContext.data to access it.
"""
_state = threading.local()
_state.data = {}
def __init__(self, **data):
self._data = data
def __enter__(self):
self._prev_data = self.__class__.data
self.__class__._state.data = self._data
def __exit__(self, *exc):
self.__class__._state.data = self._prev_data
del self._prev_data
return False
def get_current_request_id():
return ThreadRequestContext.data['request_id']
@guozhihua12

This comment has been minimized.

Copy link

@guozhihua12 guozhihua12 commented Apr 14, 2017

def get_current_request_id():
return ThreadRequestContext.data['request_id']

I have used your code in my production environment, I met a problem.Can you give me some advice?

exceptions:KeyError: 'request_id'
File "/home//handlers/baseHandlers.py", line 37, in on_finish
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/scoping.py", line 93, in remove
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/util/_collections.py", line 995, in has
File "/home/deploy/uline/uline/utils/tor.py", line 50, in get_current_request_id

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment