AttributeError: 'int' object has no attribute '_sa_instance_state'

49,909

the problem is this:

post = Post(body=form.body.data,
            timestamp=datetime.utcnow(),
            thread=thread.id,
            author=g.user.id)

you want to work with ORM objects, not primary key columns:

post = Post(body=form.body.data,
            timestamp=datetime.utcnow(),
            thread=thread,
            author=g.user)

the error means that an integer is being interpreted as an ORM object.

Share:
49,909
Ganye
Author by

Ganye

Updated on November 22, 2020

Comments

  • Ganye
    Ganye over 3 years

    I'm working on forum template using Flask. When I attempt creating a new thread in the browser using forms, SQLAlchemy throws an AttributeError. The problem showed up when I tried implementing a one-to-many relationship with Forum-to-Thread and a one-to-many relationship with Thread-to-User.

    models.py

    class User(db.Model):
      id = db.Column(db.Integer, primary_key=True)
      username = db.Column(db.String(32), index=True, unique=True)
      password = db.Column(db.String(32), index=True)
      email = db.Column(db.String(120), index=True, unique=True)
      role = db.Column(db.SmallInteger, default=ROLE_USER)
    
      posts = db.relationship('Post', backref='author', lazy='dynamic')
    
    class Forum(db.Model):
      id = db.Column(db.Integer, primary_key=True)
      title = db.Column(db.String(128))
      description = db.Column(db.Text)
    
      threads = db.relationship('Thread', backref='forum', lazy='dynamic')
    
    class Thread(db.Model):
    
      id = db.Column(db.Integer, primary_key=True)
      title = db.Column(db.String(128))
      author= db.Column(db.String(32))
      timestamp = db.Column(db.DateTime)
      forum_id = db.Column(db.Integer, db.ForeignKey('forum.id'))
    
      posts = db.relationship('Post', backref='thread', lazy='dynamic')
    
    class Post(db.Model):
    
      id = db.Column(db.Integer, primary_key=True)
      body = db.Column(db.Text)
      timestamp = db.Column(db.DateTime)
      thread_id = db.Column(db.Integer, db.ForeignKey('thread.id'))
      user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    

    All the new posts/threads and handled within views.py

    views.py

    @app.route('/forum/id=<id>/submit', methods=['GET','POST'])
    @login_required
    def new_thread(id):
      form = ThreadForm()
      forum = Forum.query.filter_by(id=id).first()
      if form.validate_on_submit():
        thread = Thread(title=form.title.data,
                        author=g.user.username,
                        timestamp=datetime.utcnow())
        db.session.add(thread)
        db.session.flush()
        post = Post(body=form.body.data,
                    timestamp=datetime.utcnow(),
                    thread=thread.id,
                    author=g.user.id)
        db.session.add(post)
        db.session.commit()
        flash('Post successful.')
        return redirect(url_for('forum_index', id=id))
      return render_template('forum/thread_submit.html', title=forum.title, form=form)