SQLAlchemy: лучший способ обновления с декларативным? - PullRequest
42 голосов
/ 13 апреля 2010

Я новичок в SQLAlchemy.

Допустим, у меня есть пользовательская таблица в декларативном режиме:

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

Когда я знаю идентификатор пользователя без загруженного в сеанс объекта, я обновляю такого пользователя следующим образом:

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

Мне не нравится использовать User.__table__, я должен перестать беспокоиться об этом?

Есть ли лучший способ сделать это?

Спасибо!

Ответы [ 3 ]

60 голосов
/ 14 апреля 2010

Есть также некоторые возможности обновления на уровне ORM. Он еще не обрабатывает сложные ситуации, но для тривиального случая однострочного обновления (или массового обновления) работает нормально. Он даже просматривает любые уже загруженные объекты и также применяет обновление к ним. Вы можете использовать это так:

session.query(User).filter_by(id=123).update({"name": u"Bob Marley"})
17 голосов
/ 13 апреля 2010

Вы работаете на уровне здесь, а не на уровне модели / объекта / объекта. Уровень предложения ниже сопоставляемых объектов. И да, нужно что-то сделать, чтобы преобразовать одни термины в другие.

Вы также можете остаться на уровне объекта и сделать:

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

но это будет значительно медленнее, так как это приведет к построению отображаемого объекта. И я не уверен, что это более читабельно.

В приведенном вами примере я вижу наиболее естественное и «правильное» решение. Я бы не стал беспокоиться о маленькой __table__ магии.

2 голосов
/ 13 мая 2015

Аналогичные функции доступны с помощью метода update() объекта Table.

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')

Чтобы использовать User.__table__, как это делается в SQLAlchemy.

...