-
-
Save mitechie/1134869 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
# Yummy constants to use in the Application | |
class System(MyEnum): | |
"""Enum type for the Users System level access""" | |
_enum = { | |
'hotalert': 'HotAlert', | |
'dashboard': 'Dashboard', | |
'defect': 'Defect', | |
} | |
class Role(meta.Base): | |
"""Roles this user has in with the components in the system""" | |
__tablename__ = "user_roles" | |
userid = Column(Integer, | |
ForeignKey('users.id'), | |
primary_key=True, | |
autoincrement=False | |
) | |
system = Column(MyEnumType(System, 255), primary_key=True) | |
level = Column(MyEnumType(Roles, 255)) | |
@reconstructor | |
def _load(self): | |
"""On loading the object instance from the db, also load the Enum""" | |
self.System = System(self.system) | |
self.Level = Roles(self.level) | |
assert Role.system == System.hotalert | |
assert Role.System.desc == "HotAelrt" | |
# the base of all of this | |
class MyEnumMcs(type): | |
"""MCS for the Enum objects so we can access _enum as class property | |
Allows: | |
System.hotalert | |
Without needing a System() instance for the normal getattr to access | |
""" | |
def __getattr__(mcs, key): | |
if key in mcs._enum.iterkeys(): | |
return key | |
else: | |
raise AttributeError(key) | |
class MyEnum(object): | |
"""Enum-like object type | |
Each implementation need only extend MyEnum and define the dict _enum | |
""" | |
__metaclass__ = MyEnumMcs | |
# default empty property | |
# override this in child classes with values | |
_enum = {} | |
def __init__(self, val): | |
self._val = val | |
def __getattr__(self, name): | |
"""If this is for desc return our value""" | |
if name == 'desc': | |
return object.__getattribute__(self, '_enum')[self._val] | |
else: | |
raise AttributeError(name) | |
@classmethod | |
def to_list(cls, inverse=False): | |
"""Return a list of tuples for key/value for select elements | |
:param inverse: need to inverse for FormAlchemy, it uses the tuples | |
opposite of the webhelper for select boxes | |
""" | |
if inverse: | |
vals = [(string, val) for val, string in cls._enum.iteritems()] | |
return sorted(vals, key=lambda key: key[0]) | |
else: | |
vals = [(val, string) for val, string in cls._enum.iteritems()] | |
return sorted(vals, key=lambda key: key[1]) | |
class MyEnumType(types.TypeDecorator): | |
"""SqlAlchemy Custom Column Type MyEnumType | |
This works in partnership with a MyEnum object | |
""" | |
impl = types.Unicode | |
_enum = {} | |
def __init__(self, enum_obj, *args, **kwargs): | |
"""Init method | |
:param enum_obj: The class that this column should be limited to | |
e.g. severity = Column(MyEnumType(Severity, 255)) | |
for a unicode column that has a length allowance of 255 characters | |
""" | |
types.TypeDecorator.__init__(self, *args, **kwargs) | |
self.enum_obj = enum_obj | |
def process_bind_param(self, value, dialect): | |
"""Going in translate the value to the Pretty version of the string""" | |
# allow setting to None for empty value | |
if value is None or value in self.enum_obj._enum.iterkeys(): | |
return value | |
elif value == '': | |
return None | |
else: | |
assert False, "%s -- %s" % (value, self._enum) | |
def process_result_value(self, value, dialect): | |
"""Going OUT get the short version of the string""" | |
return value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment