Skip to content

Instantly share code, notes, and snippets.

@mitechie
Created August 9, 2011 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mitechie/1134869 to your computer and use it in GitHub Desktop.
Save mitechie/1134869 to your computer and use it in GitHub Desktop.
# 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