this works  (been working on getting this kind of thing into recipes/docs/books)

from sqlalchemy import Column, Integer, ForeignKey, String
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.orm import relationship

Base = declarative_base()

class Mixin(object):
    @declared_attr
    def foob(cls):
        cls.Blah = Blah = type("%sBlah" % cls.__name__, 
            (Base, ),
            dict(
                __tablename__ = 'blah_%s' % cls.__tablename__,
                id = Column(Integer, primary_key=True),
                name_id = Column(Integer, ForeignKey(cls.id))
            )
        )

        return relationship(Blah)

class Name(Mixin, Base):
    __tablename__ = "name"

    id = Column(Integer, primary_key=True)
    name = Column(String)


class Name2(Mixin, Base):
    __tablename__ = "name2"

    id = Column(Integer, primary_key=True)
    name = Column(String)

print Name2.foob.contains(Name2.Blah())



On Apr 25, 2011, at 9:28 PM, Andrey Petrov wrote:

> Looks like this almost-sorta works:
> 
> class TagMixin(object):
>     @declared_attr
>     def TagClass(cls):
>         class Tag(BaseModel):
>             __tablename__ = "tag_%s" % cls.__tablename__
> 
>             id = Column(types.Integer, primary_key=True)
>             time_created = Column(types.DateTime, default=datetime.now, 
> nullable=False)
> 
>             row_id = Column(types.Integer, ForeignKey(cls.id), index=True)
>             name = Column(types.String, nullable=False, index=True)
> 
> # This part breaks with... sqlalchemy.exc.InvalidRequestError: Table 
> 'tag_user' is already defined for this MetaData instance. 
> #    @declared_attr
> #    def tags(cls):
> #        return orm.relationship(cls.TagClass, backref='tagged')
> 
> class User(BaseModel, TagMixin):
>     __tablename__ = 'user'
> 
>     id = Column(types.Integer, primary_key=True)
>     ...
> 
> The appropriate tables do get generated on create_all(). But as soon as I 
> touch the User.TagClass attribute, it barfs with the same error again:
> 
> InvalidRequestError: Table 'tag_user' is already defined for this MetaData 
> instance.  Specify 'extend_existing=True' to redefine options and columns on 
> an existing Table object.
> 
>  
>  
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalchemy@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.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@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