AttributeError: 'str' Object Has No Attribute '_sa_instance_state'
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'"