Thanks, Michael.
On May 6, 7:48 am, Michael Bayer <[email protected]> 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 [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.