-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathframework.py
More file actions
84 lines (69 loc) · 2.87 KB
/
framework.py
File metadata and controls
84 lines (69 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import os
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, ForeignKey
from sqlalchemy.types import String, Integer
import cherrypy
from cherrypy.process import wspbus, plugins
# Helper to map and register a Python class a db table
Base = declarative_base()
class SAEnginePlugin(plugins.SimplePlugin):
def __init__(self, bus, url):
"""
The plugin is registered to the CherryPy engine and therefore
is part of the bus (the engine *is* a bus) registery.
We use this plugin to create the SA engine. At the same time,
when the plugin starts we create the tables into the database
using the mapped class of the global metadata.
Finally we create a new 'bind' channel that the SA tool
will use to map a session to the SA engine at request time.
"""
plugins.SimplePlugin.__init__(self, bus)
self.url = url
self.sa_engine = None
self.bus.subscribe("bind", self.bind)
def start(self):
self.sa_engine = create_engine(self.url, echo=True)
Base.metadata.create_all(self.sa_engine)
def stop(self):
if self.sa_engine:
self.sa_engine.dispose()
self.sa_engine = None
def bind(self, session):
session.configure(bind=self.sa_engine)
class SATool(cherrypy.Tool):
def __init__(self):
"""
The SA tool is responsible for associating a SA session
to the SA engine and attaching it to the current request.
Since we are running in a multithreaded application,
we use the scoped_session that will create a session
on a per thread basis so that you don't worry about
concurrency on the session object itself.
This tools binds a session to the engine each time
a requests starts and commits/rollbacks whenever
the request terminates.
"""
cherrypy.Tool.__init__(self, 'on_start_resource',
self.bind_session,
priority=20)
self.session = scoped_session(sessionmaker(autoflush=True,
autocommit=False))
def _setup(self):
cherrypy.Tool._setup(self)
cherrypy.request.hooks.attach('on_end_resource',
self.commit_transaction,
priority=80)
def bind_session(self):
cherrypy.engine.publish('bind', self.session)
cherrypy.request.db = self.session
def commit_transaction(self):
cherrypy.request.db = None
try:
self.session.commit()
except:
self.session.rollback()
raise
finally:
self.session.remove()