Jonathan Ong
Jonathan Ong

Reputation: 20325

Self-referential tables with polymorphism in SQLAlchemy

So I'm having issues with my model right now. I came across these two (1) (2) questions which helped me a lot, but now I'm stuck. Here's my current code:

class Post(Base):
    __tablename__ = 'post'
    id = Column(Integer, primary_key=True)
    type = Column('type', String(10))
    created = Column(TIMESTAMP(), default=datetime.now())
    updated = Column(TIMESTAMP(), default=datetime.now())
    poster_id = Column(Integer, ForeignKey('person.id'))
    poster = relationship('Person', backref=backref('posts'))
    __mapper_args__ = {'polymorphic_on': type}

class Comment(Post):
    __tablename__ = 'comment'
    __mapper_args__ = {'polymorphic_identity': 'comment', 'inherit_condition': (id == Post.id)}
    id = Column(Integer, ForeignKey('post.id'), primary_key=True)
    post_id = Column(Integer, ForeignKey('post.id'))
    post = relationship('Post', primaryjoin=('Comment.post_id == Post.id'), backref=backref('comments'), remote_side='Post.id')
    text = Column(Text)

The current error I'm getting is:

TypeError: Incompatible collection type: int is not list-like

What am I doing wrong? Thanks.

Upvotes: 0

Views: 819

Answers (1)

SingleNegationElimination
SingleNegationElimination

Reputation: 156238

id is a really unfortunate name for a column; id is a built-in function, and so it's always defined. If you had chosen a less mainstream name for your primary keys, you would be seeing a different error and it would be obvious;

class Comment(Post):
    __tablename__ = 'comment'
    __mapper_args__ = {'polymorphic_identity': 'comment', 'inherit_condition': (id == Post.id)}
#                                                                               ^^

That id refers to __builtins__.id, which is a function that returns the address of a python object. Probably not what you meant.

Easy solution: move __mapper_args__ below the line where you alias id to mean your actual table Column.

Upvotes: 3

Related Questions