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

> One more thought:
> 
> Is there a sane way to hide a schema object within another schema object?
> 
> Specifically, I want to make a factory method (or maybe a class decorator) 
> which generates these Tag schemas onto specific tables. Something along the 
> lines of:
> 
> @Taggable
> class User(BaseModel)
>     __tablename__ = "user"
> 
> The Taggable class decorator would generate another table called "tag_user" 
> and attach the appropriate relationship attributes to the User class. I'm 
> thinking it'll also attach the anonymous Tag declarative class to the User 
> class as User.TagClass or somesuch.
> 
> Is this reasonable? Is there a better way to do this than monkey-patching the 
> User class in the Taggable decorator?
> 
> One fantasy I had was if you could do...
> 
> class TaggableMixin(object):
>     @declared_attr
>     def TaggableClass(cls):
>         class Tag(BaseModel):
>             __tablename__ = "tag_%s" % cls.__tablename__
>             # ... schema here
> 
> class User(BaseModel, TaggableMixin):
>     # ...
> 
> Perhaps I should try it but I don't imagine this will work.

you should create tables inside of @declared_attr.   Usually I'm using straight 
Table in there but declared class should work too (though you might get a 
warning about the same class created twice, unless you do some kind of 
uniqifying, it probably would be nice to fix declarative to not call any 
@declared_attr twice).     For the "already have this table in this metadata" 
issue use the table argument "keep_existing=True".

Otherwise, I do this exact pattern you have above except explicitly:

class UserTag(TagBase, Base):
    __tablename__ = 'user_tag'

class User(Taggable, Base):
    tag_cls = UserTag

TagBase and Taggable do the rest of the work.

*maybe* this works too:

class User(Taggable, Base):
    class tag_cls(TagBase, Base):
        __tablename__ = 'user_tag'


You could also use an event like "instrument_class" or "mapper_configured" , 
associated with mapper() and would look for Taggable subclasses.


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