Mapping Collected Tables to Composition in Object Relational Databases

I recently started using SQLAlchemy without any SQL knowledge. The problem I am facing is how to introduce polymorphic behavior. Consider a Reddit-like web app as an example; we have a model for Article

and one for Comment

, and both can be voted on:

class Article(Base):
    id       = Column(Integer, primary_key = True)
    data     = Column(Text)
    comments = relationship('Comment')
    #... more article-related attributes
    votes      = relationship('Vote')
    vote_ups   = Column(Integer, default = 0)
    vote_downs = Column(Integer, default = 0) 

class Comment(Base):
    id   = Column(Integer, primary_key = True)
    data = Column(Text)
    #... more comment-related attributes
    votes      = relationship('Vote')
    vote_ups   = Column(Integer, default = 0)
    vote_downs = Column(Integer, default = 0)

      

I would like to separate the voting attributes that are common to both models, so I don't have to repeat the code for each model that can be voted on.

My first thought was to create a new model VotesComponent

containing the attributes as such,

class VotesComponent(Base):
    votes      = relationship('Vote')
    vote_ups   = Column(Integer)
    vote_downs = Column(Integer)

      

and establishing many-one relationships with models Comment

and Article

.

Digging into the SQLAlchemy documentation, I later learned that something similar can be achieved using attached table inheritance . This seems really handy at first as an extra level of indirection is avoided (i.e. one can refer to comment.votes instead of comment.votes_component.votes), but one big drawback I see with my limited understanding is that multiple inheritance is not supported, whereas the earlier method could add as many Components to the model.

So my question is what are the advantages of using inheritance mapping over composition, and when is it preferable and why? In this case, which of the two (or possibly different) methods would you recommend?

EDIT . I should mention that I want to be able to request the "Vote" part on separate models so that I can handle the vote polymorphically.

+3


source to share


1 answer


This is a good question, but borderline off-topic here because questions that invite opinion-based responses have been frowned upon on stackoverflow. However, here is my personal trick (I really want not to start a flamwar).

So my question is, what are the benefits of using composition inheritance matching, and when is it preferable and why?

In most OO languages, inheritance is associated with is-a questions, and composition is associated with has-a questions. Composition in Python is often implemented through multiple inheritance, so the question of composition versus inheritance is a bit odd. The language promotes the Duck typing style , so "is-a" questions are considered more idiomatic.



When we talk about ORMs, there are other implications as well: how is inheritance implemented under the hood? Some implementations will propagate object data across multiple tables and execute SQL JOINs, others will use separate tables and execute SQL UNIONs. IMHO this is not something you should be wasting energy on. The first reason is because it's transparent to you, that's the whole point when using an ORM. Second, you lack the knowledge to judge which one is best for your specific use case (you will need to dive into SQL and specific implementation details of multiple RDBMs to understand the performance implications).

My advice is to implement it using your preferred programming style, trust the ORM implementations, and let the performance work with the DBA.

+1


source







All Articles