-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathalchmanager.py
78 lines (60 loc) · 2.45 KB
/
alchmanager.py
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
"""
alchmanager
"""
__version__ = '0.0.2'
__author__ = 'Roman Gladkov'
import types
import inspect
from sqlalchemy.orm.mapper import Mapper
from sqlalchemy.orm.query import Query
from sqlalchemy.orm.session import Session
from sqlalchemy.ext.declarative.api import DeclarativeMeta
__all__ = ['ManagedQuery', 'ManagedSession']
not_doubleunder = lambda name: not name.startswith('__')
not_under = lambda name: not name.startswith('_')
class ManagedQuery(Query):
"""Managed Query object"""
def __init__(self, entities, *args, **kwargs):
self.binds = {}
entity = None
if isinstance(entities, Mapper):
entity = entities.entity
if isinstance(entity, DeclarativeMeta):
if hasattr(entity, '__manager__'):
manager_cls = entity.__manager__
for fname in filter(not_doubleunder, dir(manager_cls)):
fn = getattr(manager_cls, fname)
setattr(self, fname, types.MethodType(fn, self))
if isinstance(entities, tuple) and len(entities):
entity = entities[0]
if entity and isinstance(entity, DeclarativeMeta):
if hasattr(entity, '__manager__'):
manager_cls = entity.__manager__
for fname in filter(not_doubleunder, dir(manager_cls)):
fn = getattr(manager_cls, fname)
self.binds.update({fname: fn})
self.__rebind()
super(ManagedQuery, self).__init__(entities, *args, **kwargs)
def __getattribute__(self, name):
""" Rebind function each function call
:param name: str
:return: any
"""
returned = object.__getattribute__(self, name)
if name != '_ManagedQuery__rebind' and \
(inspect.isfunction(returned) or inspect.ismethod(returned)):
# print('called ', returned.__name__)
self.__rebind()
return returned
def __rebind(self):
if len(self.binds):
for fname, fn in self.binds.items():
setattr(self, fname, types.MethodType(fn, self))
class ManagedSession(Session):
def load_manager(self):
def loader(manager_cls):
for fname in filter(not_doubleunder, dir(manager_cls)):
fn = getattr(manager_cls, fname)
if not hasattr(self._query_cls, fname):
setattr(self._query_cls, fname, fn)
return loader