SQLAlchemy: a better way for update with declarative?

Question:

Let’s say I have a user table in declarative mode:

class User(Base):
    __tablename__ = 'user'
    id = Column(u'id', Integer(), primary_key=True)
    name = Column(u'name', String(50))

When I know user’s id without object loaded into session, I update such user like this:

ex = update(User.__table__).where(User.id==123).values(name=u"Bob Marley")
Session.execute(ex)

I dislike using User.__table__, should I stop worrying with that?

Is there a better way to do this?

Asked By: Hadrien

||

Answers:

You’re working on clause level here, not on model/entity/object level. Clause level is lower than mapped objects. And yes, something have to be done to convert one terms into others.

You could also stay on object level and do:

session = Session()
u = session.query(User).get(123)
u.name = u"Bob Marley"
session.commit()

but it will be significantly slower since it leads to the mapped object construction. And I’m not sure that it is more readable.

In the example your provided I see the most natural and “right” solution. I would not worry about little __table__ magic.

Answered By: nkrkv

There’s also some update capability at the ORM level. It doesn’t handle any tricky cases yet but for the trivial case of single row update (or bulk update) it works fine. It even goes over any already loaded objects and applies the update on them also. You can use it like this:

session.query(User).filter_by(id=123).update({"name": u"Bob Marley"})
Answered By: Ants Aasma

Similar functionality is available via the update() method on Table object.

class User(Base):
    __tablename__   = 'user'
    id = Column('id', Integer(), primary_key=True)
    name = Column('name', String(50))

stmt = User.__table__.update().where(User.id==5).values(name='user #5')

To use User.__table__ is how its done in SQLAlchemy.

Answered By: The Demz
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.