1

Following is the Topic Model:

class Topic(db.Model):
    __tablename__ = 'topics'
    topic_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    topic_name = db.Column(db.String(200), unique=True, nullable=False)

    posts = db.relationship('Association', back_populates='topic')

Following is the Post model:

class Post(db.Model):
    __tablename__ = 'posts'
    post_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text, nullable=False)
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    likes = db.Column(db.Integer, default=0)
    dislikes = db.Column(db.Integer, default=0)

    author_id = db.Column(db.Integer, db.ForeignKey('users.user_id'))
    author = db.relationship('User', back_populates='posts')

    topics = db.relationship('Association', back_populates='post')

Following is the Association Model:

class Association(db.Model):
    __tablename__ = 'post_topic_assoc'
    post_id = db.Column('post_id', db.ForeignKey('posts.post_id'), primary_key=True)
    topic_id = db.Column('topic_id', db.ForeignKey('topics.topic_id'), primary_key=True)

    post = db.relationship('Post', back_populates='topics')
    topic = db.relationship('Topic', back_populates='posts')

Here is my view function:

def create(user_id):
    form = PostForm()

    query = db.session.query(Topic.topic_id, Topic.topic_name)
    topics = query.all()
    form.topics.choices = topics

    if request.method == 'POST' and form.validate_on_submit():
        choice_instances = list(map(Topic.query.get, form.topics.data))
        new_post = Post(title=form.title.data,
                        content=form.content.data,
                        author=current_user)
        new_post.topics.extend(choice_instances)
        db.session.add(new_post)
        db.session.commit()

        flash('You post has been created')
        return redirect(url_for('blueprint_user.user_home',
                                user_id=current_user.user_id))

The error just says this:

KeyError: 'post'

I execution does stops at new_post.topics.extend(choice_instances) line.

Why am I unable to insert the topics using .extend()? Is anything wrong with the way I created the many-many relationship?

Please click here for the complete traceback.

Most of the SO questions (like this) that I came across were using the association table method and not association model. Even in those the .append() or .extend() is working but not in my code.

Please guide me I am a beginner in SqlAlchemy.

vjp
  • 303
  • 1
  • 3
  • 7
  • What happens if you try `new_post.topics = choice_instances`. Also, try reading the many-to-many relationship [documentation](https://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html#many-to-many) and try to duplicate the example. – Joost Nov 13 '18 at 16:26
  • Your relationship is configured as a relationship with `Association`, yet you're trying to extend with a list of `Topic`. When asking debugging questions please include full tracebacks, not just the error message. – Ilja Everilä Nov 13 '18 at 16:44
  • @Joost I replaced the line `new_post.topics.extend(choice_instances)` with `new_post.topics = choice_instances` but I got the same error (KeyError: 'post') – vjp Nov 13 '18 at 17:52
  • @IljaEverilä Sorry. I included a link in the description, it has the complete traceback. Please take a look. – vjp Nov 13 '18 at 17:54
  • @IljaEverilä how is the association object pattern different from many-many? The documentation says the following, "The association object pattern is a variant on many-to-many: it’s used when your association table contains additional columns beyond those which are foreign keys to the left and right tables." – vjp Nov 13 '18 at 18:20

0 Answers0