On Jul 19, 2007, at 3:05 PM, Jacques Naude wrote:
> Having tried Django some time ago, I already had a set of such
> tuple constants, which I wanted to simply reuse in Elixir. I did
> think that an enum column type in Elixir would be very handy (like
> a tried in a version using SQLObject) to have though. One can
> probably pick it up from the lower SQLAlchemy somehow, but I have
> no idea how to tackle it at that level without going the whole
> SQLAlchemy route, which I didn't - I reallt like the look and feel
> of Elixir.
I have no idea if I'm on a daft path with this -- I'm very new to
Elixir and SA -- well, new to enlightened DB programming in any real
sense...up to this point, I've used DB's only as simple, persistent
data stores with nothing fancy and no real smarts to the
implementation, so like I said, I don't know if I'm doing something
silly, but here's what I do...
We're starting to work on a project with Elixir where we'll need enum
types like MySQL has (I've used MySQL a bit for other work, so I got
used to using enum cols)... so this is what I came up with, cobbled
together primarily from an SA recipe I found out on the web (in other
words, I take little credit for it, but am glad to share if it's
useful)...
#############
"""enum.py"""
from elixir import *
from sqlalchemy import types
class Enum(TypeDecorator):
"""This class adds support for ENUM fields, similar in
functionality to the
ENUM column type in MySQL"""
impl = types.Unicode
def __init__(self, values, empty_to_none=False):
'''
contruct an Enum type
values : a list of values that are valid for this column
empty_to_none : treat the empty string '' as None
'''
if values is None or len(values) is 0:
raise exceptions.AssertionError('Enum requires a list of
values')
self.empty_to_none = empty_to_none
self.values = values
# the length of the string/unicode column should be the
longest string
# in values
size = max([len(v) for v in values if v is not None])
super(Enum, self).__init__(size)
def convert_bind_param(self, value, engine):
if self.empty_to_none and value is '':
value = None
if value not in self.values:
raise AssertionError('"%s" not in Enum.values' % value)
return super(Enum, self).convert_bind_param(value, engine)
def convert_result_value(self, value, engine):
if value not in self.values:
raise AssertionError('"%s" not in Enum.values' % value)
return super(Enum, self).convert_result_value(value, engine)
#############
and then a test to show that it'll fail if you try to use something
not in it's values list:
#############
"""test_enum.py"""
from sqlalchemy import create_engine
from enum import *
engine = create_engine('sqlite:///')
metadata.connect(engine)
def test_enum():
class TestPerson(Entity):
with_fields(
gender = Field(Enum(["m","f"])))
create_all()
t = TestPerson()
t.gender = "m"
objectstore.flush()
t.gender = "f"
objectstore.flush()
try:
t.gender = "W" #this should fail
objectstore.flush()
except AssertionError:
pass
else:
assert False #make sure this fails if it doesn't raise the
exception above
drop_all()
objectstore.clear()
#############
Is that Elixir friendly enough for your needs or have I completely
missed the boat here?
-ted
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"SQLElixir" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/sqlelixir?hl=en
-~----------~----~----~----~------~----~------~--~---