Can't Set Attribute On Result Objects In Sqlalchemy Flask
Solution 1:
place_collections = Place.query.filter_by(county='BKK')
will return you a collection of Place
objects. This is analogous to session.query(Place).filter_by(county='BKK')
in plain vanilla SQLAlchemy.
However, from the SQLAlchemy docs:
The Query also accepts ORM-instrumented descriptors as arguments. Any time multiple class entities or column-based entities are expressed as arguments to the query() function, the return result is expressed as tuples
The key point being that when you specify specific columns to query as you have done here:
places = db.session.query(Place.roll_number, Place.name,
Place.website, Place.address, Place.distance).\
outerjoin(Rank, Rank.place_id == Place.place_id)
the result is expressed as a collection of tuples
.
My first impression was that can't set attribute
was a strange error message to receive from trying to assign an attribute value to a tuple
, so I tried it:
>>> t = tuple()
>>> t.attribute = 9
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple'object has no attribute 'attribute'
That's not the error message that you received.
So I performed a query similar to your second one (the model is just something from a project that I had open):
>>>q = session.query(Racecard.id, Racecard.meeting)>>>a_result = q[0]>>>type(a_result)
<class 'sqlalchemy.util._collections.result'>
Right, so we aren't getting a tuple, we get a sqlalchemy.util._collections.result
object. But..
>>> issubclass(type(a_result), tuple)
True
So, the sqlalchemy.util._collections.result
is a type of tuple
.
If we try to assign a value to an attribute that is not one of the columns that were queried:
>>> a_result.newattribute ='something'
Traceback (most recent calllast):
File "<stdin>", line 1, in<module>
AttributeError: 'result' object has no attribute 'newattribute'
That error message is very similar to the one that we got before when assigning an attribute to a plain tuple
.
So why did you get a different error message? The result
object is actually more like a namedtuple
:
>>>from collections import namedtuple>>>Racecard = namedtuple('Racecard', 'id, meeting')>>>rc = Racecard(1, 'Doomben')>>>rc.meeting = 'Eagle Farm'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
Which is the same error message that you are getting.
So, the sqlalchemy.util._collections.result
object supports attribute access of the column names, but as it is a tuple
it is still immutable, so you cannot write to those attributes.
To fix your specific error (unless there was some reason that you were specifically querying only those columns) change your places
query to:
places = db.session.query(Place).outerjoin(Rank, Rank.place_id == Place.place_id)
Solution 2:
Another possible cause for this error ("AttributeError: can't set attribute" error) is when you have both a column and a property with an identical name.
It happened to me with an @property
that I had previously added (and forgotten about), then created a column with the same name.
Post a Comment for "Can't Set Attribute On Result Objects In Sqlalchemy Flask"