On Nov 15, 2010, at 12:41 PM, Joril wrote:

> Hi everyone!
> I'm trying to port my application from SA 0.5.8 to 0.6.5, and I'm
> having a problem with __mapper_args__.. :/
> 
> The application uses the declarative plugin, and every class derives
> from a customized declarative base that aims to add to each one the
> "version_id_col".
> 
> Right now the code is like this:
> 
> 
> class MyMeta(DeclarativeMeta):
> 
>    def __init__(cls, classname, bases, dict_):
>        cls.version = Column(Integer)
>        cls.__mapper_args__ = { "version_id_col" : cls.version }
>        return DeclarativeMeta.__init__(cls, classname, bases, dict_)
> 
> Base = declarative_base(metaclass=MyMeta)
> 
> class Entity(Base):
> 
>     __tablename__ = "entities"
>     ....whatever...
> 
> 
> but I think I'm missing something, since even a simple
> 
> print Entity().__mapper__.version_id_col
> 
> produces a "(no name)" instead of something like "entities.version",
> so I'm guessing that some part of SA doesn't "see" the
> version_id_col...?
> 
> I understand that SA 0.6 includes a "Declarative Mixin" feature, but
> that would require to touch-up every class declaration to include the
> mixin, am I right? It'd be no big deal, but I'd prefer to keep that
> "complexity" away, if it's possible... :)

First off, I can't reproduce your issue:

from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base
from sqlalchemy import *

class MyMeta(DeclarativeMeta):

   def __init__(cls, classname, bases, dict_):
       cls.version = Column(Integer)
       cls.__mapper_args__ = { "version_id_col" : cls.version }
       return DeclarativeMeta.__init__(cls, classname, bases, dict_)

Base = declarative_base(metaclass=MyMeta)

class Entity(Base):

    __tablename__ = "entities"
    
    id = Column(Integer, primary_key=True)

assert Entity.__mapper__.version_id_col is Entity.version.property.columns[0]
assert isinstance(Entity.__mapper__.version_id_col, Column)
assert Entity.__mapper__.version_id_col.name == 'version'
assert str(Entity.__mapper__.version_id_col) == 'entities.version'

Second, "(no name)" is produced if the column object hasn't been named.  Make 
sure you aren't doing something that's causing cls.version to get copied or 
overwritten or conflicted, thereby making the one you're sticking in 
__mapper_args__ incorrect.   A good candidate here is if you're using joined 
table inheritance.


Second, if you want to switch to newer declarative features, just stick your 
__mapper_args__ on Base:

class Base(object):
    version = Column(Integer)

    @declared_attr
    def __mapper_args__(cls):
        return {'version_id_col':cls.version}

Base = declarative_base(cls=Base)


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

Reply via email to