On Monday, February 24, 2014 12:55:16 PM UTC-8, Michael Bayer wrote:
>
>
> On Feb 24, 2014, at 2:41 PM, Luke <lmer...@gmail.com <javascript:>> 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")
>
>
Michael,

Thank you for the care you put into your support here and on stackoverflow. 
I will consider your advice carefully. I had moved to this more complex, 
inherited design after implementing simple, independent tables (as you 
suggested). And you have confirmed that it's probably not worth the 
trouble. I am concerned that the more complex my mapped classes are, the 
more complex, and thus slow, my queries will be. I'm not even to the point 
where I have thought about tuning queries or caching. I am not a trained 
programmer and I have probably bitten off more than I can chew. But, in any 
case, that's not your concern. 

Thank you again for the help.

Luke

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

Reply via email to