On Nov 6, 2012, at 5:42 PM, John Anderson wrote:

> I have a mixin that declares a primary key but would like to dynamically 
> override the name of it.
> 
> So for instance this is the base:
> 
> class BaseModel(object):
>     @declared_attr
>     def pk(self):
>         return sa.Column(sa.Integer, autoincrement=True, primary_key=True)
> 
> but in some circumstances people want to use my mixin but declare the primary 
> key property as id instead.
> 
> So I want to be able to do something class
> 
> class SubClass(BaseModel):
>     _idAttribute = 'id'
> 
> and have it use id in the database and has the class property to reference 
> instead of pk.
> 
> 
> Is this possible?

The name assigned to the class and the name given to the Column when it emits 
CREATE TABLE are two different things.

The "name" is what you'll see in CREATE TABLE, easy enough, "return 
Column('id', ...)"

As far as the name assigned to the class, in classical mappings the "key" of 
the Column is used, and it might be nice if declarative looked at column.key in 
this case, however it doesn't.  There is a way this could probably be hacked 
on, by creating a custom __mapper__ classmethod and converting all the Columns 
with custom .keys to be mapped with that name.  a little ugly, though.

of course the blunt tool that works in all cases is the custom metaclass, but 
that approach is fairly tedious and is probably a lot uglier than just the 
__mapper__ hack above.

Another way that is a little verbose but is the least intrusive is to just use 
more @declared_attrs.

in 0.8, @declared_attr can be specified on a non-mixin, so this works there:

class A(BaseModel, Base):
    __tablename__ = "a"

    @declared_attr
    def pk(self):
        return None

    @declared_attr
    def id(self):
        return BaseModel.pk

if 0.7, another mixin can do it:

class SubBaseModel(BaseModel):
    @declared_attr
    def pk(self):
        return None

    @declared_attr
    def id(self):
        return BaseModel.pk

class A(SubBaseModel, Base):
    __tablename__ = "a"

i can show you the __mapper__ hack if that's not good enough.



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