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
-~----------~----~----~----~------~----~------~--~---

Reply via email to