4

When trying to update a row value in a table using Flask-SQLAlchemy, I get the following error:

>>> row.meta_value = "new value"
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/daniel/Documents/work/breakfast4you/backend/venv/lib/python3.10/site-packages/sqlalchemy/engine/row.py", line 219, in __setattr__
    raise AttributeError("can't set attribute")
AttributeError: can't set attribute

I'm testing the code before implementing into the actual file, so I'm running it through flask shell. I've ran other queries through flask shell so I know it's not a problem with it.

The table belongs to a MySQL database connected through a MariaDB engine. This is its table model:

t_aus_postmeta = db.Table(
    'aus_postmeta',
    db.Column('post_id', db.BigInteger, nullable=False, server_default=db.FetchedValue()),
    db.Column('meta_key', db.String(255, 'utf8mb4_unicode_ci')),
    db.Column('meta_value', db.String(collation='utf8mb4_unicode_ci'))
)

And this is the query I'm running to retrieve the row.

>>> row = db.session.query(t_aus_postmeta).\
            filter(t_aus_postmeta.c.post_id == 740).\
                filter(t_aus_postmeta.c.meta_key == "_billing_shipment").\
                    first()

I was able to run the same query using plain SQL through DBeaver:

UPDATE aus_postmeta 
SET meta_value = "Cumpleaños"
WHERE post_id = 740
AND meta_key = "_billing_shipment";

Taking into account the accepted answer to this almost identical question, I tried:

  • Querying only one row, to avoid a tuple object.
  • Avoid a .filter like filter(meta.c.meta_key.in_([<array of meta_keys>])) (which was my first intention, since I need to edit several rows).

Following the advise on that same question, I also ran the following test to see if the object was of type tuple . I doubted it, (since it's only one row), but still:

>>> row
(740, '_billing_shipment', 'Cumpleaños')
>>> type(row)
<class 'sqlalchemy.engine.row.Row'>
>>> issubclass(type(row), tuple)
False

EDIT: Looking further into my package versions,

SQLAlchemy == 1.4.31
Flask-SQLAlchemy == 2.5.1

This GitHub comment suggests that it was fixed on Flask-SQLAlchemy 2.5 and subsequently, this answer states that it's no longer necessary to downgrade SQLAlchemy, so my package versions should have this issue fixed.

What else could be causing this error? How can I fix it?

LeperAffinity666
  • 364
  • 4
  • 14

1 Answers1

0

Since I had the exacte same Location where the Error is raised (... engine/row.py", line 219,), maybe this helps you as much as it helped me:

This answer explains the difference between session.execute(select(Object)) and session.query(Object) and if you use have a Row object you need to unpack it.

Use:

row["Object"].meta_value = "new value"

Instead of:

row.meta_value = "new value"
ndndinger
  • 73
  • 5
  • Hey, using this I got the following error: sqlalchemy.exc.NoSuchColumnError: Could not locate column in row for column 'Object' – Fabíola Mar 01 '23 at 20:32