SQLAlchemy:声明式更新的更好方法?
假设我有一个用户表,使用的是声明式模式:
class User(Base):
__tablename__ = 'user'
id = Column(u'id', Integer(), primary_key=True)
name = Column(u'name', String(50))
当我知道用户的ID,但没有把这个用户的对象加载到会话中时,我会这样更新这个用户:
ex = update(User.__table__).where(User.id==123).values(name=u"Bob Marley")
Session.execute(ex)
我不太喜欢使用 User.__table__
,我应该停止担心这个吗?
有没有更好的方法来做到这一点?
3 个回答
4
在表对象上,可以通过 update()
方法实现类似的功能。
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')
在 SQLAlchemy 中,使用 User.__table__
就可以做到这一点。
20
你现在是在处理子句层面,而不是模型、实体或对象层面。子句层面比映射对象要低一些。没错,确实需要做一些工作来把一个术语转换成另一个术语。
你也可以停留在对象层面,做如下操作:
session = Session()
u = session.query(User).get(123)
u.name = u"Bob Marley"
session.commit()
但这样会明显变慢,因为这会导致映射对象的构建。而且我不确定这样是否更容易理解。
在你提供的例子中,我认为这是最自然和“正确”的解决方案。我不会太担心小的__table__
魔法。
65
在ORM层面上也有一些更新的功能。虽然它还不能处理一些复杂的情况,但对于简单的单行更新(或者批量更新)来说,它运行得很好。它甚至会检查已经加载的对象,并对它们进行更新。你可以这样使用它:
session.query(User).filter_by(id=123).update({"name": u"Bob Marley"})