Given the arbitrary example below, I can't ever recall actually using the FooKeyword association table other than to set up mappings. I came up with a brute force method to generate the "secondary" table for me automatically, and I'm hoping someone can show me a better way to do this.
My goal was to take something like this (imports excluded for brevity): class Keyword(Base): __tablename__ = 'keyword' id = Column(Integer, primary_key = True) name = Column(String, unique = True, nullable = False) class Foo(Base): __tablename__ = 'foo' id = Column(Integer, primary_key = True) ... snip ... keywords = relationship(Keyword, secondary='foo_keyword') class FooKeyword(Base): __tablename__ = 'foo_keyword' foo_id = Column(Integer, ForeignKey('foo.id'), primary_key = True, nullable = False) keyword_id = Column(Integer, ForeignKey('keyword.id'), primary_key = True, nullable = False) And replace it with something like this: class Keyword(Base): .... snip (same as before) .... class Foo(Base): .... snip .... keywords = generate_many_to_many_for_me('Foo', 'Keyword') So in the code above, the FooKeyword table would get generated automatically, and a relationship like "relationship(Keyword, secondary='foo_keyword') would automatically get returned. Here is my super naive solution that sort of works: """So below here, a call like "secondary_relationship(Foo, Keyword)" would automatically generate a class called FooKeyword that is mapped to a table called 'foo_keyword'. It then uses these to return a relationship equivalent to relationship(Keyword, secondary='foo_keyword'). You can specify the generated tablename using the tblname arg like so: "secondary_relationship(Foo, Keyword, "my_tablename") """ def secondary_relationship(cls1, cls2, tblname = None): new_class_name = cls1.__name__ + cls2.__name__ tn1, tn2 = cls1.__tablename__, cls2.__tablename__ tbl = '%s_%s' % (tn1, tn2) if tblname is None else tblname # Generate the "FooKeyword" table t = type(new_class_name, (Base,), { '__tablename__': tbl, tn1 + '_id': Column(Integer, ForeignKey('%s.id' % tn1), primary_key = True, nullable = False), tn2 + '_id': Column(Integer, ForeignKey('%s.id' % tn2), primary_key = True, nullable = False) }) return relationship(cls2, secondary = tbl) # the Keyword and Foo classes identical to first example... class Keyword(Base): .... snip (same as before) .... class Foo(Base): .... snip (same as before except keywords defined below) .... # And this builds the many to many for us without having to build FooKeyword class... Foo.keywords = secondary_relationship(Foo, Keyword) # You could also do like below to control the tablename generated: Foo.keywords = secondary_relationship(Foo, Keyword, 'my_tablename') This actually works, but you can't use this until *after* the definition for Foo. I'm looking for a way to do this inline in Foo like so: class Foo(Base): .... snip .... keywords = secondary_relationship('Foo', 'Keyword') Is there a better way? I have spent the better part of the day reading the source code to see how the declarative extension allows string class names for relationship, but I still haven't been able to figure this out... Thanks, Jeff Peck -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out.