Метод update класса Query
Метод update класса Query
выполняет массовое обновление строк в таблице,
соответствующих текущему запросу. В отличие от
изменения атрибутов ORM-объектов, метод не
загружает объекты в сессию, а сразу формирует
SQL-запрос UPDATE. Первым параметром
передается словарь со значениями для обновления.
Вторым необязательным параметром
synchronize_session задается стратегия
синхронизации уже загруженных объектов в сессии.
Синтаксис
Query.update(values, [synchronize_session])
Пример
Давайте создадим таблицу статей и обновим
статус всех записей через метод update:
from sqlalchemy import create_engine, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(50))
status: Mapped[str] = mapped_column(String(20))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article 1', status='draft'),
Article(title='article 2', status='draft'),
Article(title='article 3', status='draft'),
])
session.commit()
res = session.query(Article).update({'status': 'published'})
session.commit()
print(res)
for article in session.query(Article).all():
print(article.title, article.status)
Результат выполнения кода:
3
article 1 published
article 2 published
article 3 published
Итоговый SQL запрос:
UPDATE articles SET status=?
Пример
Давайте обновим записи не все сразу, а только
отфильтрованные методом filter:
from sqlalchemy import create_engine, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(50))
status: Mapped[str] = mapped_column(String(20))
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article 1', status='draft', num=1),
Article(title='article 2', status='draft', num=2),
Article(title='article 3', status='draft', num=3),
])
session.commit()
res = session.query(Article).filter(Article.num > 1).update({'status': 'published'})
session.commit()
print(res)
for article in session.query(Article).all():
print(article.title, article.status)
Результат выполнения кода:
2
article 1 draft
article 2 published
article 3 published
Итоговый SQL запрос:
UPDATE articles SET status=? WHERE articles.num > ?
Пример
Давайте обновим сразу несколько полей и
используем параметр synchronize_session
со значением 'fetch':
from sqlalchemy import create_engine, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(50))
text: Mapped[str] = mapped_column(String(100))
status: Mapped[str] = mapped_column(String(20))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add(Article(title='article', text='old text', status='draft'))
session.commit()
res = session.query(Article).update(
{'title': 'article updated', 'status': 'published'},
synchronize_session='fetch'
)
session.commit()
print(res)
article = session.query(Article).first()
print(article.title, article.status)
Результат выполнения кода:
1
article updated published
Смотрите также
-
класс
Query,
который представляет ORM-запрос к базе данных -
метод
filter,
который накладывает условие на обновляемые записи -
метод
delete,
который выполняет массовое удаление записей -
метод
with_for_update,
который блокирует строки при выборке