|
22 | 22 | from .model import Model
|
23 | 23 | from .model import NameMixin
|
24 | 24 | from .pagination import Pagination
|
| 25 | +from .pagination import RowPagination |
25 | 26 | from .pagination import SelectPagination
|
26 | 27 | from .query import Query
|
27 | 28 | from .session import _app_ctx_id
|
@@ -814,7 +815,8 @@ def paginate(
|
814 | 815 |
|
815 | 816 | The statement should select a model class, like ``select(User)``. This applies
|
816 | 817 | ``unique()`` and ``scalars()`` modifiers to the result, so compound selects will
|
817 |
| - not return the expected results. |
| 818 | + not return the expected results. To paginate a compound select, use |
| 819 | + :meth:`paginate_rows` instead. |
818 | 820 |
|
819 | 821 | :param select: The ``select`` statement to paginate.
|
820 | 822 | :param page: The current page, used to calculate the offset. Defaults to the
|
@@ -846,6 +848,54 @@ def paginate(
|
846 | 848 | count=count,
|
847 | 849 | )
|
848 | 850 |
|
| 851 | + def paginate_rows( |
| 852 | + self, |
| 853 | + select: sa.sql.Select[t.Any], |
| 854 | + *, |
| 855 | + page: int | None = None, |
| 856 | + per_page: int | None = None, |
| 857 | + max_per_page: int | None = None, |
| 858 | + error_out: bool = True, |
| 859 | + count: bool = True, |
| 860 | + ) -> Pagination: |
| 861 | + """Apply an offset and limit to a select statment based on the current page and |
| 862 | + number of items per page, returning a :class:`.Pagination` object. |
| 863 | +
|
| 864 | + Unlike :meth:`paginate`, the statement may select any number of |
| 865 | + columns, like ``select(User.name, User.password)``. Regardless of how |
| 866 | + many columns are selected, the :attr:`.Pagination.items` attribute of |
| 867 | + the returned :class:`.Pagination` instance will contain :class:`Row |
| 868 | + <sqlalchemy.engine.Row>` objects. |
| 869 | +
|
| 870 | + Note that the ``unique()`` modifier is applied to the result. |
| 871 | +
|
| 872 | + :param select: The ``select`` statement to paginate. |
| 873 | + :param page: The current page, used to calculate the offset. Defaults to the |
| 874 | + ``page`` query arg during a request, or 1 otherwise. |
| 875 | + :param per_page: The maximum number of items on a page, used to calculate the |
| 876 | + offset and limit. Defaults to the ``per_page`` query arg during a request, |
| 877 | + or 20 otherwise. |
| 878 | + :param max_per_page: The maximum allowed value for ``per_page``, to limit a |
| 879 | + user-provided value. Use ``None`` for no limit. Defaults to 100. |
| 880 | + :param error_out: Abort with a ``404 Not Found`` error if no items are returned |
| 881 | + and ``page`` is not 1, or if ``page`` or ``per_page`` is less than 1, or if |
| 882 | + either are not ints. |
| 883 | + :param count: Calculate the total number of values by issuing an extra count |
| 884 | + query. For very complex queries this may be inaccurate or slow, so it can be |
| 885 | + disabled and set manually if necessary. |
| 886 | +
|
| 887 | + .. versionadded:: 3.2 |
| 888 | + """ |
| 889 | + return RowPagination( |
| 890 | + select=select, |
| 891 | + session=self.session(), |
| 892 | + page=page, |
| 893 | + per_page=per_page, |
| 894 | + max_per_page=max_per_page, |
| 895 | + error_out=error_out, |
| 896 | + count=count, |
| 897 | + ) |
| 898 | + |
849 | 899 | def _call_for_binds(
|
850 | 900 | self, bind_key: str | None | list[str | None], op_name: str
|
851 | 901 | ) -> None:
|
|
0 commit comments