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