SQLAlchemy:使用声明式更新的更好方法?

Had*_*ien 45 python sqlalchemy declarative

我是一个SQLAlchemy noob.

假设我在声明模式下有一个用户表:

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

当我知道用户的id没有加载到会话中的对象时,我更新这样的用户:

ex = update(User.__table__).where(User.id==123).values(name=u"Bob Marley")
Session.execute(ex)
Run Code Online (Sandbox Code Playgroud)

我不喜欢使用User.__table__,我应该不再担心吗?

有一个更好的方法吗?

谢谢!

Ant*_*sma 61

ORM级别还有一些更新功能.它还没有处理任何棘手的情况,但对于单行更新(或批量更新)的简单情况,它工作正常.它甚至可以覆盖任何已加载的对象,并对它们应用更新.你可以像这样使用它:

session.query(User).filter_by(id=123).update({"name": u"Bob Marley"})
Run Code Online (Sandbox Code Playgroud)

  • @Brendan`过滤器`和`filter_by`是不同的方法.前者将表达式作为参数,而后者采用关键字参数. (3认同)
  • @Kira:迟到的回复,但我会添加它以防其他人需要它.session.query(User).filter_by(id = 123).update({User.name:"Bob Marley"}) (3认同)
  • @RichardLaw不,`FOR UPDATE`不是`UPDATE`语句的一部分,SQLA只是忽略了`with_for_update()`. (3认同)
  • 这没有考虑用户为列分配的变量名称 - 如果name声明为user_name = Column("name",String(50)),则b/c将失败,需要列的实际名称.谁能解释为什么会这样? (2认同)

nkr*_*rkv 17

你在这里处理子句级别,而不是模型/实体/对象级别.子句级别低于映射对象.是的,必须采取措施将一个术语转换为其他术语.

您还可以保持对象级别并执行:

session = Session()
u = session.query(User).get(123)
u.name = u"Bob Marley"
session.commit()
Run Code Online (Sandbox Code Playgroud)

但它会明显变慢,因为它会导致映射的对象构造.而且我不确定它是否更具可读性.

在您提供的示例中,我看到了最自然和"正确"的解决方案.我不会担心小__table__魔法.