【问题标题】:How to paginate without fetching the entire table?如何在不获取整个表格的情况下进行分页?
【发布时间】:2019-04-16 01:09:26
【问题描述】:

我正在尝试将 table(来自 Azure 上的远程数据库)中获取的数据分页可以在代码中看到,如下:

    import json
    import pyodbc

    # Includes other imports

    def query_db(query):
        """
        Function that queries the required table in the DB
        """

        cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server}; \
                               SERVER=db.database.windows.net; \
                               DATABASE=DB; UID=id; PWD=pwd')
        cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8')
        cur = cnxn.cursor()
        cur.execute(query)

        # Fetches the entire table ## This is causing the lagg
        r = [dict( (cur.description[i][0], value) for i, value in enumerate(row) ) for row in cur.fetchall()]

        cur.connection.close()

        return(r)

    @api_view(['GET'])
    def get(request):
        paginator = PageNumberPagination()
        my_query = query_db("select * from Client_Table")

        result_page = paginator.paginate_queryset(my_query, request)
        json_output = json.dumps(result_page, cls=DjangoJSONEncoder)

        return paginator.get_paginated_response(json_output)

这里的问题是:我首先获取整个表格,然后对其进行分页。我如何分页,而不必获取整个表格? 注意:我没有使用 Django 模型

【问题讨论】:

  • 如果是我,我宁愿从远程数据库中获取所有数据并缓存在redis中。
  • 有趣的想法(虽然我从未使用过任何缓存库或 Redis)。但是,这将如何工作?我的表中有大约 5000 条记录,每页分页 15 条记录。我会缓存什么(如果我要缓存)?
  • 似乎您可能会在运行查询后尝试选择 fetchone() 来查询您想要多少表? docs.djangoproject.com/en/2.2/topics/db/sql/…
  • 我认为使用Model.objects.count() 来获取total_page 和Model.objects.all()[:15] 来限制查询可能对你有用。
  • @WaketZheng 我没有使用 Django 模型!!

标签: python pagination django-rest-framework


【解决方案1】:

我建议从数据库中调用过滤后的数据,因为它是分页的,您可以调用带有跳过和限制逻辑的 API 来解析下一个或预测数据。

SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

例如 在开始时,您需要前 10 行,然后从您的应用程序中传递参数 的跳过=0&limit=10

SELECT * FROM TableName ORDER BY id OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;

现在如果你点击next,想要下10 ROWS,你只需要传递skip=10&limit=10的参数

SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

同样,您也可以通过任意传递限制来更改每页的结果。

根据您的代码,我希望您使用的是 GET 方法

@api_view(['GET'])
def get(request):
    paginator = PageNumberPagination()
    skip=request.params.get('skip')
    limit=request.params.get('limit')
    query = "SELECT * FROM Client_table ORDER BY ID OFFSET "+ skip + " ROWS FETCH NEXT " + limit+" ROWS ONLY"
    my_query = query_db(query)
    result_page = paginator.paginate_queryset(my_query, request)
    json_output = json.dumps(result_page, cls=DjangoJSONEncoder)

    return paginator.get_paginated_response(json_output)

【讨论】:

  • 这就是我正在寻找的解决方案。非常感谢!
猜你喜欢
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 2019-01-19
  • 2017-02-16
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
相关资源
最近更新 更多