Метод offset
Метод offset класса Select
задает количество строк, которые нужно
пропустить в начале результата запроса.
Первым параметром метод принимает целое
число - количество пропускаемых строк.
Обычно используется вместе с методом
limit для постраничной выборки.
Метод возвращает новый объект Select,
поэтому его можно вызывать в цепочке
с другими методами. В сгенерированном
SQL-запросе появляется конструкция
OFFSET.
Синтаксис
select(...).offset(count)
Пример
Давайте создадим таблицу articles
и заполним ее несколькими строками:
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(200))
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', text='text 1', status='draft', num=1),
Article(title='article 2', text='text 2', status='published', num=2),
Article(title='article 3', text='text 3', status='published', num=3),
Article(title='article 4', text='text 4', status='draft', num=4),
Article(title='article 5', text='text 5', status='published', num=5),
])
session.commit()
Пример
Давайте пропустим первые две строки и выведем оставшиеся заголовки:
from sqlalchemy import create_engine, select, 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(200))
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', text='text 1', status='draft', num=1),
Article(title='article 2', text='text 2', status='published', num=2),
Article(title='article 3', text='text 3', status='published', num=3),
Article(title='article 4', text='text 4', status='draft', num=4),
Article(title='article 5', text='text 5', status='published', num=5),
])
session.commit()
stmt = select(Article.title).offset(2)
res = session.execute(stmt).scalars().all()
print(res)
Результат выполнения кода:
['article 3', 'article 4', 'article 5']
Пример
Давайте скомбинируем offset
и limit для постраничной
выборки - вторая страница по две
записи:
from sqlalchemy import create_engine, select, 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(200))
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', text='text 1', status='draft', num=1),
Article(title='article 2', text='text 2', status='published', num=2),
Article(title='article 3', text='text 3', status='published', num=3),
Article(title='article 4', text='text 4', status='draft', num=4),
Article(title='article 5', text='text 5', status='published', num=5),
])
session.commit()
stmt = (
select(Article.title)
.order_by(Article.num)
.limit(2)
.offset(2)
)
res = session.execute(stmt).scalars().all()
print(res)
Результат выполнения кода:
['article 3', 'article 4']
Пример
Давайте посмотрим итоговый SQL-запрос,
который генерирует метод offset:
from sqlalchemy import create_engine, select, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
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(200))
status: Mapped[str] = mapped_column(String(20))
num: Mapped[int]
stmt = select(Article.title).offset(3).limit(2)
print(stmt)
Итоговый SQL запрос:
SELECT articles.title
FROM articles
LIMIT :param_1 OFFSET :param_2