Enum recipe on SQLAlchemy 0.8.0 final

79 views
Skip to first unread message

Alex Grönholm

unread,
Apr 10, 2013, 5:10:49 AM4/10/13
to sqlal...@googlegroups.com
The following class works on 0.8.0b2 but not 0.8.0 final:
 
class EnumWrapper(SchemaType, TypeDecorator):
    def __init__(self, cls):
        kwargs = {'name': cls.__name__.lower()}
        self.impl = Enum(*(obj.key for obj in cls.values), **kwargs)
        self.wrapped = cls

    def _set_table(self, table, column):
        self.impl._set_table(table, column)

    def process_bind_param(self, value, dialect):
        if value is None:
            return None
        if isinstance(value, self.wrapped):
            return value.key
        elif isinstance(value, str):
            if value not in self.wrapped.symbols:
                raise TypeError('No such enum value in %s: %s' % (self.wrapped.__name__, value))
            return value
        raise TypeError('Expected %s, got %s instead' % (self.wrapped, type(value)))

    def process_result_value(self, value, dialect):
        return getattr(self.wrapped, value) if value is not None else None

The error message ("TypeError: __init__() got an unexpected keyword argument 'schema'") originates from types.py, line 1886.
Is inheriting from SchemaType still necessary? That is what seems to break things on 0.8.0 final.

Michael Bayer

unread,
Apr 10, 2013, 11:06:57 AM4/10/13
to sqlal...@googlegroups.com
Line 1886 of types.py, both in 0.8.0 and in tip, is this:

            t.drop(bind=bind, checkfirst=checkfirst)

so that doesn't seem like the line we're referring to.

Since your example lacks context, I had to modify the call to "Enum" to use a series of string names (don't know what obj.key, cls.values refer to).  From there, I managed to get a stack trace that refers to line 1863 of types.py.

In the documentation for TypeDecorator at http://docs.sqlalchemy.org/en/rel_0_8/core/types.html#sqlalchemy.types.TypeDecorator, the example includes a copy() method.   There is also a copy() method in the original Enum recipe on my blog at http://techspot.zzzeek.org/files/2011/decl_enum.py.

If the constructor of your decorated type is not compatible with the type you're wrapping, you need to provide copy() as well:

    def copy(self):
        return DeclEnumType(self.wrapped)


hope this helps !


Alex Grönholm

unread,
Apr 10, 2013, 11:33:14 AM4/10/13
to sqlal...@googlegroups.com
My bad, it was line 1866: return impltype(name=self.name, ...)

Since your example lacks context, I had to modify the call to "Enum" to use a series of string names (don't know what obj.key, cls.values refer to).  From there, I managed to get a stack trace that refers to line 1863 of types.py.

In the documentation for TypeDecorator at http://docs.sqlalchemy.org/en/rel_0_8/core/types.html#sqlalchemy.types.TypeDecorator, the example includes a copy() method.   There is also a copy() method in the original Enum recipe on my blog at http://techspot.zzzeek.org/files/2011/decl_enum.py.

If the constructor of your decorated type is not compatible with the type you're wrapping, you need to provide copy() as well:

    def copy(self):
        return DeclEnumType(self.wrapped)
Yet, the error goes away once I add something like that. Strange though, everything worked fine even without a copy() method in 0.8.0b2.

Thanks!


hope this helps !


--
You received this message because you are subscribed to a topic in the Google Groups "sqlalchemy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sqlalchemy/LE-EIznAIT4/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to sqlalchemy+...@googlegroups.com.
To post to this group, send email to sqlal...@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages