Created
August 1, 2017 03:37
-
-
Save ficapy/f5c6abfe00b7b5ecd075c8c321e5e999 to your computer and use it in GitHub Desktop.
tornado 数据库操作
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Author: ficapy | |
import threading | |
import functools | |
import tornado.ioloop | |
import tornado.web | |
from sqlalchemy import Column, create_engine | |
from sqlalchemy.dialects.mysql import INTEGER, BIT, VARCHAR | |
from sqlalchemy.ext.declarative import declarative_base | |
from sqlalchemy.orm import scoped_session, sessionmaker | |
from tornado import stack_context | |
from tornado import gen | |
ULINE_DB = 'postgresql+psycopg2://xxx:xxx@localhost/xxx' | |
class Metaclass(type): | |
@property | |
def data(cls): | |
if not hasattr(cls._state, 'data'): | |
return {} | |
return cls._state.data | |
class ThreadRequestContext(object, metaclass=Metaclass): | |
_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'] | |
engine = create_engine(ULINE_DB, | |
encoding='utf-8', | |
echo=False, | |
pool_recycle=600, | |
pool_size=20, | |
max_overflow=100) | |
db = scoped_session(sessionmaker(bind=engine, | |
), scopefunc=get_current_request_id) | |
Base = declarative_base(bind=engine) | |
class BaseHandler(tornado.web.RequestHandler): | |
def prepare(self): | |
db() | |
def on_finish(self): | |
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) | |
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) | |
class MainHandler(BaseHandler): | |
@gen.coroutine | |
def get(self): | |
db.query(User.id).first() | |
db.remove() | |
yield gen.sleep(1) | |
db.query(User.id).first() | |
self.write("Hello, world") | |
def make_app(): | |
return tornado.web.Application([ | |
(r"/", MainHandler), | |
]) | |
if __name__ == "__main__": | |
Base.metadata.create_all(checkfirst=True) | |
app = make_app() | |
app.listen(8888) | |
tornado.ioloop.IOLoop.current().start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
参考 https://gist.github.com/Hackforid/7130a5d59463186e217e