Skip to content Skip to sidebar Skip to footer

AttributeError: 'str' Object Has No Attribute '_sa_instance_state'

I want to evaluate the values that are linked to two different users. I created a different table to keep track of a user's previous experiences and their interested experiences an

Solution 1:

Here's a really small example that reproduces the error:

class Parent(Base):
    id = sa.Column(sa.Integer, primary_key=True)
    child = relationship('Child', backref='parent')


class Child(Base):
    id = sa.Column(sa.Integer, primary_key=True)
    parent_id = sa.Column(sa.Integer, sa.ForeignKey('parent.id'))


if __name__ == '__main__':
    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine)
    parent = Parent()
    child = Child(parent=parent)
    s = Session()
    s.add(parent)
    s.commit()
    s.query(Child).filter_by(parent='a string').first()  # this line causes error

Which raises:

Traceback (most recent call last):
  File "55876558.py", line 27, in <module>
    s.query(Child).filter_by(parent='a string').first()
  File "C:\Users\peter_000\.virtualenvs\test-_0Fb_hDQ\lib\site-packages\sqlalchemy\orm\query.py", line 1689, in filter_by
    for key, value in kwargs.items()]
  File "C:\Users\peter_000\.virtualenvs\test-_0Fb_hDQ\lib\site-packages\sqlalchemy\orm\query.py", line 1689, in <listcomp>
    for key, value in kwargs.items()]
  File "C:\Users\peter_000\.virtualenvs\test-_0Fb_hDQ\lib\site-packages\sqlalchemy\sql\operators.py", line 344, in __eq__
    return self.operate(eq, other)
  File "C:\Users\peter_000\.virtualenvs\test-_0Fb_hDQ\lib\site-packages\sqlalchemy\orm\attributes.py", line 180, in operate
    return op(self.comparator, *other, **kwargs)
  File "C:\Users\peter_000\.virtualenvs\test-_0Fb_hDQ\lib\site-packages\sqlalchemy\orm\relationships.py", line 1039, in __eq__
    other, adapt_source=self.adapter))
  File "C:\Users\peter_000\.virtualenvs\test-_0Fb_hDQ\lib\site-packages\sqlalchemy\orm\relationships.py", line 1372, in _optimized_compare
    state = attributes.instance_state(state)
AttributeError: 'str' object has no attribute '_sa_instance_state'

Child.parent is a relationship attribute, and a good resource to help you understand how they work is here, in the official docs. The key takeaway is that they deal with other ORM objects. So, when you query on a relationship, you need to provide an ORM object. In the above example if you replace this line: s.query(Child).filter_by(parent='a string').first() with this line: s.query(Child).filter_by(parent=parent).first(), the error goes away because parent is an ORM object.

In your specific case, the error comes from this line: curr = prevExp.query.filter_by(user=user).first().expDescription, where you pass a variable user to the filter_by() method. user is defined on the line above that, user = prevExp.query.filter_by(user=current_user).first().expDescription where you query a prevExp object and once it's retrieved using first(), you then access it's expDescription attribute. The column definition of expDescription is expDescription = db.Column(db.String(400)): a string. So you are passing a str to query the relationship attribute and creating the exact situation that the simplified example above demonstrates.

The reason for the error message AttributeError: 'str' object has no attribute '_sa_instance_state', is that every ORM object has an _sa_instance_state attribute. As relationship attributes are purely for representing other ORM objects, sqlalchemy assumes that the string you have passed in is an ORM object without bothering to check first (why would it?!). A string doesn't have a _sa_instance_state attribute, and hence the AttributeError.


Post a Comment for "AttributeError: 'str' Object Has No Attribute '_sa_instance_state'"