On May 6, 2010, at 3:35 AM, George V. Reilly wrote:

> Our production database uses MySQL. For various reasons, the schema
> often uses MySQL-specific DDL. We want that represented in our
> mapper classes. We also awant to be able to exercise our SQLAlchemy
> unit tests against both local MySQL databases and SQLite databases.
> 
> Using the MySQL-specific types wasn't a problem with SA 0.5.x, but
> it is with 0.6.

would be curious to know why that is.


> I've started working around it like this:
> 
>    class MSBigInteger(sqltypes.TypeDecorator):
>        impl = sqltypes.Integer
> 
>        def load_dialect_impl(self, dialect):
>            return dialect.type_descriptor(
>                mysql.base.MSBigInteger if dialect.name == 'mysql'
> else sqltypes.INTEGER)
> 
> This approach falls apart when the type's __init__ takes custom
> parameters, such as collation or charset for the strings.
> 
>    class MSLongText(sqltypes.TypeDecorator):
>        impl = sqltypes.String
> 
>        def load_dialect_impl(self, dialect):
>            self.dialect = dialect
>            return dialect.type_descriptor(
>                mysql.base.MSLongText if dialect.name == 'mysql' else
> sqltypes.TEXT)
> 
>        def __init__(self, **kwargs):
>            # FIXME: figure out what the dialect is in __init__
> (somehow) so can call
>            # correct dialect_impl
>            if 'collation' in kwargs: del kwargs['collation']
>            if 'charset' in kwargs: del kwargs['charset']
>            super(MSLongText, self).__init__(**kwargs)
> 
> What's a good way to fix this? I'm not wedded to the TypeDecorator
> for MSBigInteger either, if there's a better approach.

your load_dialect_impl() should be returning the fully constructed instance of 
MSBigInteger, there's no need to call dialect.type_descriptor here.   If the 
type did have some DBAPI-specific subclass that needs to be invoked there, 
type_descriptor should be handed the fully constructed MSBigInteger, not the 
class.

ultimately I'd like to add a new type to SQLAlchemy core which serves the 
purpose of "delegating" some type to different backend implementations.   It 
would look like this:

Column('foo',   CompositeType(default=Integer(), 
mysql=mysql.INTEGER(precision=12))

CompositeType is a subclass of TypeDecorator and only needs to store those 
initial types, and return them within load_dialect_impl().   Since you've 
already written most of that logic yourself you can try going with that 
approach.


-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" 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/sqlalchemy?hl=en.

Reply via email to