Thanks, Michael. On May 6, 7:48 am, Michael Bayer <mike...@zzzcomputing.com> wrote: > 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 was getting errors like this: ... File "...\sqlalchemy-0.6.0-py2.6.egg\sqlalchemy\schema.py", line 1958, in create_all bind.create(self, checkfirst=checkfirst, tables=tables) File "...\sqlalchemy-0.6.0-py2.6.egg\sqlalchemy\engine\base.py", line 1504, in create self._run_visitor(ddl.SchemaGenerator, entity, connection=connection, **kwargs) ... File "...\sqlalchemy-0.6.0-py2.6.egg\sqlalchemy\sql\visitors.py", line 48, in _compiler_dispatch return getter(visitor)(self, **kw) File "...\sqlalchemy-0.6.0-py2.6.egg\sqlalchemy\sql\compiler.py", line 1136, in visit_create_table first_pk=column.primary_key and not first_pk File "...\sqlalchemy-0.6.0-py2.6.egg\sqlalchemy\dialects\sqlite \base.py", line 234, in get_column_specification colspec = self.preparer.format_column(column) + " " + self.dialect.type_compiler.process(column.type) File "...\sqlalchemy-0.6.0-py2.6.egg\sqlalchemy\engine\base.py", line 734, in process return type_._compiler_dispatch(self) File "...\sqlalchemy-0.6.0-py2.6.egg\sqlalchemy\sql\visitors.py", line 48, in _compiler_dispatch return getter(visitor)(self, **kw) AttributeError: 'SQLiteTypeCompiler' object has no attribute 'visit_TINYINT' > > 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. Like this, presumably: class MSBigInteger(sqltypes.TypeDecorator): impl = sqltypes.Integer def load_dialect_impl(self, dialect): return mysql_base.MSBigInteger() \ if dialect.name == 'mysql' else sqltypes.INTEGER() > 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. This seems to work, but it's not well tested: class CompositeType(sqltypes.TypeDecorator): def __init__(self, default_type, **kwargs): self.default_type = default_type self.dialect_types = kwargs super(CompositeType, self).__init__() def load_dialect_impl(self, dialect): return self.dialect_types.get(dialect.name, self.default_type) class MSString(CompositeType): impl = sqltypes.VARCHAR def __init__(self, length=None, **kwargs): super(MSString, self).__init__( default_type=sqltypes.VARCHAR(), mysql=mysql_base.MSString(length, **kwargs)) class ToDoElement(Base): # declarative base text = Column(MSString(256, charset='utf8'), nullable=False, default='') -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalch...@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.