2

I'm trying to add an item to my database with SQLAlchemy + Flask, but keep getting an error.

class users(db.Model):
    userid = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80))
    email = db.Column(db.String(120))
    password = db.Column(db.String(80))
    duguns = db.relationship('dugun', backref='whuser', lazy='dynamic')
    yorums = db.relationship('yorum', backref='whuser', lazy='dynamic')
    genels = db.relationship('genel', backref='whuser', lazy='dynamic')
    bilgis = db.relationship('bilgi', backref='whuser', lazy='dynamic')

class bilgi(db.Model):
    kisiselid = db.Column(db.Integer, primary_key=True)
    userid = db.Column(db.Integer, db.ForeignKey('users.userid'))
    gelinAdi = db.Column(db.String(80))
    damatAdi = db.Column(db.String(80))
    gelinFoto = db.Column(db.String(80))
    damatFoto = db.Column(db.String(80))
    gelinBio = db.Column(db.String(120))
    damatBio = db.Column(db.String(80))



@app.route("/admin", methods=["GET","POST"])
@login_required
def admin():
    form = KisiForm(request.form)
    if request.method == "POST":
        gelinAdi = form.gelinAdi.data
        gelinFoto = form.gelinFoto.data
        gelinBio = form.gelinBio.data
        damatAdi = form.damatAdi.data
        damatFoto = form.damatFoto.data
        damatBio = form.damatBio.data
        whuser = session["username"]

        kisi = bilgi(whuser = whuser, gelinAdi = gelinAdi, gelinFoto = gelinFoto, gelinBio = gelinBio, damatAdi = damatAdi, damatFoto = damatFoto, damatBio = damatBio)
        db.session.add(kisi)
        db.session.commit()
        return redirect(url_for("admin"))

    return render_template("admin/index.html",form=form)

That's the code. When I run the Python file I get this error:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/bozkurt/Desktop/davetiye/site.py", line 70, in decorated_function
    return f(*args, **kwargs)
  File "/Users/bozkurt/Desktop/davetiye/site.py", line 172, in admin
    kisi = bilgi(whuser = whuser, gelinAdi = gelinAdi, gelinFoto = gelinFoto, gelinBio = gelinBio, damatAdi = damatAdi, damatFoto = damatFoto, damatBio = damatBio)
  File "<string>", line 4, in __init__

  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/state.py", line 417, in _initialize_instance
    manager.dispatch.init_failure(self, args, kwargs)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 249, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/state.py", line 414, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/ext/declarative/base.py", line 700, in _declarative_constructor
    setattr(self, k, kwargs[k])
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py", line 229, in __set__
    instance_dict(instance), value, None)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py", line 813, in set
    value = self.fire_replace_event(state, dict_, value, old, initiator)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py", line 833, in fire_replace_event
    state, value, previous, initiator or self._replace_token)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py", line 1181, in emit_backref_from_scalar_set_event
    child_state, child_dict = instance_state(child),\
AttributeError: 'str' object has no attribute '_sa_instance_state'

AttributeError: 'str' object has no attribute '_sa_instance_state. What do I have to do?

MatsLindh
  • 49,529
  • 4
  • 53
  • 84
Berat Bozkurt
  • 111
  • 4
  • 13
  • please can you add the full traceback to identify the error ? Also, what is `whuser` for the model `bilgi` ? – PRMoureu Jul 15 '18 at 19:13

1 Answers1

3

You have columns defined as backrefs:

bilgis = db.relationship('bilgi', backref='whuser', lazy='dynamic')

Meaning that the value they're set to represents an ORM object - not a single string. You do however send in just the string (username) when creating the object:

whuser = session["username"]
kisi = bilgi(whuser = whuser, ...)

Make sure to give the user object returned from the ORM instead:

bilig(whuser=<actual user object from the ORM>, ..)

You can do that by fetching the user from the ORM first:

user = users.query.filter_by(username=whuser).first()

And then using that value when creating the dependent object:

bilig(whuser=user, ..)
MatsLindh
  • 49,529
  • 4
  • 53
  • 84
  • 1
    `whuser = session["username"]` - you're setting the value here yourself. If you have the query in front of that, use the session var directly. – MatsLindh Jul 15 '18 at 21:39
  • I am having the same issue as above and cannot reproduce the solution. Maybe I don't understand what you mean by _Make sure to give the user object returned from the ORM instead:_? Here is my similar app set up https://dpaste.com/CF7YLX27P. The error stems from `post = Post(body = form.comment.data, author = user.username)` Kindly, explain why you suggest the change above to fix the error – Gitau Harrison Oct 19 '20 at 10:04
  • 1
    @GitauHarrison Your `author` is defined as a backref to an instance of the `User` class. You're giving it a string (the `user.username` value). `author=user` would be a reference to the actual user class as returned from your ORM (i.e. the object as it's present in the ORM, not the user name as a string). – MatsLindh Oct 19 '20 at 10:08
  • Note to self, and to others: Be VERY careful to make sure that you don't accidentally set a column name and a relationship property name to be the same name. Busted my head for two hours trying to figure out why this was happening in to me. Turns out my User model had an email column as well as an email relationship to an Email table (reason for this is because the column was for registration purposes and the Email table was to map Email objects to multiple users, a many to many relationship) – OzzyTheGiant Aug 30 '21 at 23:12