15

I followed the (two) examples in this question: SQLAlchemy: a better way for update with declarative?

And I'm finding that a model update does not happen when using sqlite with flask-sqlalchemy on Ubuntu Linux. The very simplest example doesn't work for me:

class Task:
    id= db.Column(db.Integer, primary_key=True)
    name= db.Column(db.String(32), unique=True)
    desc= db.Column(db.String(255), unique=False)
    state= db.Column(db.Boolean)

    # ...

@app.route("/task/<int:id>/update",methods=["POST"])
def toggle_state(id):
    db.session.query(Task).get(id).update({"state":True})
    log.info("state is now: " + str(Task.query.get(id).state))
    # prints "state is now: False"

First time using flask/sqlalchemy, so I assume I'm missing something obvious.

Community
  • 1
  • 1
Kevin
  • 24,871
  • 19
  • 102
  • 158

1 Answers1

33

So I tried several different things. Here's what didn't work, and what finally did work:

Didn't work:

# this will throw an exception, "AttributeError: 'Task' object has no attribute 'update'"
db.session.query(Task).get(id).update({"state":state})
db.session.commit()

# this was the example in the linked SO thread:
# does nothing
db.session.query(Task).filter_by(id=id).update({"state":state})

#this also does nothing
task = Task.query.filter_by(id=id)
task.state = state
db.session.commit()

#not this either
task = Task.query.get(id)
task.state = state
db.session.commit()

Did work:

#ok this works:
db.session.query(Task).filter_by(id=id).update({"state":state})
db.session.commit()

#and also this:
task = db.session.query(Task).get(id)
task.state = state
db.session.commit()
Nathan Wailes
  • 9,872
  • 7
  • 57
  • 95
Kevin
  • 24,871
  • 19
  • 102
  • 158
  • For declarative style: `session.query(Task).filter_by(id=id).update({"state":state})` – ATH Mar 06 '21 at 00:31
  • can anyone explain why ? – Hritik Jan 22 '23 at 12:33
  • I'm facing the same issue, it's soooo weird. – KAs Feb 08 '23 at 10:04
  • Yes, I'd also like to know why... – daddydan May 16 '23 at 17:08
  • I had used syntax synchronize_session="fetch" in the update too - thinking that was mandated. But the session.commit() was the bit that worked - maybe there is an auto commit option too on the session. I will add I was using `id.in_()` functionality too and it did the updates in bulk and that was ok after the commit. – JGFMK Aug 07 '23 at 15:45