On Feb 24, 2014, at 2:41 PM, Luke <lmerg...@gmail.com> wrote: > Hi, > > > > class Response(Writing): > # All responses are associated with Writing. Writing/Articles may have > # several responses > # > __tablename__ = 'response' > id = Column('id', ForeignKey('writing.id'), primary_key=True) > respondee_id = Column('respondee', ForeignKey('article.id'), > nullable=False) > > # So, No, I don't know what I'm doing here... > respondee = relationship( > 'Response', backref='respondant', > primaryjoin=('Writing.respondant' == 'Response.respondee')) > __mapper_args__ ={ > 'polymorphic_identity': 'response', }
1. for the syntax on primaryjoin as a string, it has to be all one string: primaryjoin = “Writing.id == Response.respondee_id” see the examples at: http://docs.sqlalchemy.org/en/rel_0_9/orm/relationships.html#relationship-primaryjoin http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/declarative.html#configuring-relationships 2. The primaryjoin is between columns, which are accessed using the attribute name given, such as Writing.id. not the name of a relationship (respondent). 3. the relationship joins two tables between primary key columns and foreign key columns. In this case, you’re saying you’d like “response.respondee” to refer to “article.id”, so you’d be setting up primary join in that way…..but 4. ..the mapping doesn’t seem to make sense in that regard, you have Response linked to Response, and not Article. If Article is just one kind of Writing, and Response belongs to any kind of Writing, it would be: class Response(Writing): __tablename__ = 'response' id = Column('id', ForeignKey('writing.id'), primary_key=True) respondee_id = Column(ForeignKey('writing.id'), nullable=False) writing = relationship(Writing, remote_side=Writing.id, backref="responses", primaryjoin=Writing.id == respondee_id) __mapper_args__ = {'polymorphic_identity': 'response', 'inherit_condition': id == Writing.id} inherit condition is needed as “response” now has two ways to link directly to “writing”. 5. On the topic of “not an expert in SQL”, I will say that this kind of design where “everything inherits from joined-table X” is extremely common for people I see moving from a pure OO background to beginning to mix SQL into their modeling. It’s not “wrong” per se and can be a useful design, but in my experience is overused, and it also leads to queries that are very complicated on the render side and often not very performant. You should consider very carefully how many columns will actually be on “Writing” as well as how many kinds of “sub-tables” will really be needed to import these columns on “writing”; additionally, you should consider how much of a need you will have to query across all kinds of “Writing” objects at the same time. In practice, this use case is rare; your app will either need to see lists of Articles, or it will need to see the list of Responses given a parent Writing. If Writing has only a handful of columns, it would be much more efficient and simple from both a storage and a querying perspective to just have a “response” table, an “article” table, and then a few columns on both that just happen to be the same. From the object modeling side, you can keep Response and Article as subclasses of Writing, however you can have Writing itself be a non-mapped mixin or __abstract__ class. The mapping becomes extremely simple and from a SQL perspective much more succinct and performant: class Writing(Base): __abstract__ = True id = Column(Integer, primary_key=True) # gets copied out to subclasses class Article(Writing): __tablename__ = 'article' class Response(Writing): __tablename__ = 'response' respondee_id = Column(ForeignKey('article.id'), nullable=False) writing = relationship(Article, backref="responses")
signature.asc
Description: Message signed with OpenPGP using GPGMail