如何在Flask中使用sqlalchemy核心进行分页?

时间:2016-09-06 05:59:38

标签: python pagination sqlalchemy

我只使用带有 SQLAlchemy核心的flask框架。从'select'语句返回的结果集包含数千条记录。我想使用分页来避免内存错误。如何动态地为任何页面使用游标获取api GET方法的JSON输出?我已经尝试了How to use cursor() for pagination?中接受的解决方案,但无法完全正确。请指导。使用PostgreSQL 9.4 我尝试过的选项:

1

<html>
<head>
    <script src="angleoftriangle.js"></script>
    <link rel="stylesheet" type="text/css" href="angleoftriangle.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
</head>
<body>
<div id="coverbox">
    <div id="equilateral-try">
    </div>
    <form id="text" onsubmit="return areaval()">
        <p id="heading1"style="position:absolute;top:8%;left:20%;font-size:22px;color:black;">Acute Triangle</p>
        <p id="heading5"style="position:absolute;top:42%;left:20%;font-size:20px;color:black;">abc<90deg.</p>
        <input type="text" value ="" id="number" style="position:absolute;width:8%;height:4%;left:60%;top:40%;outline:none;border:none;font-size:25px;background-color:transparent;" placeholder="b"required>
        <input type="text" value ="" id="acure" style="position:absolute;width:8%;height:4%;left:78%;top:31%;outline:none;border:none;font-size:25px;z-index:4;background-color:transparent;" placeholder="h"required>
        <input type="text" value ="" id="pmet" style="position:absolute;width:8%;height:4%;left:42%;top:25%;outline:none;border:none;font-size:25px;z-index:6;background-color:transparent;" placeholder="a"required>
        <input type="text" value ="" id="cmet" style="position:absolute;width:8%;height:4%;left:88%;top:25%;outline:none;border:none;font-size:25px;z-index:5;background-color:transparent;" placeholder="c"required>
        <button style="position:absolute;height:20px;left:70%;top:41%;">sol</button>
    </form>
    <div id="result"style="position:absolute;top:55%;left:20%;font-size:20px;color:#878787;"></div>
    <div id="step4.1"style="position:absolute;top:60%;left:20%;font-size:20px;color:#878787;"></div>
    <div id="result2.2"style="position:absolute;top:68%;left:20%;font-size:20px;color:#878787;"></div>
    <div id="step4.6"style="position:absolute;top:73%;left:20%;font-size:20px;color:#878787;"></div>
    <svg height="16%" width="14%"id="strightline">
        <line x1="30" y1="0" x2="30" y2="105" style="stroke:black;stroke-width:2" />
    </svg>
</div>

<div id="coverbox11">
    <div id="right-try">
    </div>
    <form id="text1" onsubmit="return rightang()">
        <p id="heading1"style="position:absolute;top:7%;left:32%;font-size:22px;color:black;">Rightangle Triangle</p>
        <p id="heading5"style="position:absolute;top:42%;left:43%;font-size:20px;color:black;"> a=90degree.</p>
        <input type="text" value ="" id="oppsite" style="position:absolute;width:8%;height:4%;left:38%;top:23%;outline:none;border:none;font-size:25px;background-color:transparent;" placeholder="a"required>
        <input type="text" value ="" id="hidgt" style="position:absolute;width:8%;height:4%;left:48%;top:23%;outline:none;border:none;font-size:25px;z-index:20;background-color:transparent;" placeholder="h"required>
        <input type="text" value ="" id="adjacent" style="position:absolute;width:8%;height:4%;left:53%;top:37%;outline:none;border:none;font-size:25px;z-index:4;background-color:transparent;" placeholder="b"required>
        <input type="text" value ="" id="hyper" style="position:absolute;width:8%;height:4%;left:68%;top:23%;outline:none;border:none;font-size:25px;z-index:6;background-color:transparent;" placeholder="c"required>
        <button style="position:absolute;height:20px;left:64%;top:38%;">sol</button>
    </form>
    <div id="raitresult"style="position:absolute;top:55%;left:43%;font-size:20px;color:#878787;"></div>
    <div id="step5.1"style="position:absolute;top:60%;left:43%;font-size:20px;color:#878787;"></div>
    <div id="periresult2"style="position:absolute;top:70%;left:43%;font-size:20px;color:#878787;"></div>
    <div id="step5.5"style="position:absolute;top:75%;left:43%;font-size:20px;color:#878787;"></div>
    <div id="periresult3"style="position:absolute;top:85%;left:43%;font-size:20px;color:#878787;"></div>
    <div id="step5.8"style="position:absolute;top:90%;left:43%;font-size:20px;color:#878787;"></div>
</div>

<div id="coverbox12">
    <div id="obtuse-try">
    </div>
    <svg height="15%" width="15%"id="strightline3">
        <path id="lineAB" d="M 100 150 l 70 -200" stroke="black" stroke-width="2" fill="none" />
    </svg>
    <form id="text2" onsubmit="return obtuseang()">
        <p id="heading16"style="position:absolute;top:8%;left:20%;font-size:22px;color:black;">Obtuse Triangle</p>
        <p id="heading17"style="position:absolute;top:42%;left:30%;font-size:20px;color:black;">a>90degree.</p>
        <input type="text" value ="" id="oppsite1" style="position:absolute;width:8%;height:4%;left:48%;top:38%;outline:none;border:none;font-size:25px;background-color:transparent;" placeholder="b"required>
        <input type="text" value ="" id="oppsite2" style="position:absolute;width:8%;height:4%;left:58%;top:28%;outline:none;border:none;font-size:25px;z-index:16;background-color:transparent;" placeholder="h"required>
        <input type="text" value ="" id="oppsite6" style="position:absolute;width:8%;height:4%;left:71%;top:23%;outline:none;border:none;font-size:25px;z-index:16;background-color:transparent;" placeholder="c"required>
        <input type="text" value ="" id="oppsite7" style="position:absolute;width:8%;height:4%;left:36%;top:23%;outline:none;border:none;font-size:25px;z-index:16;background-color:transparent;" placeholder="a"required>
        <button style="position:absolute;height:20px;left:58%;top:39%;">sol</button>
    </form>
    <div id="raitresult43"style="position:absolute;top:55%;left:30%;font-size:20px;color:#878787;"></div>
    <div id="step6.1"style="position:absolute;top:60%;left:30%;font-size:20px;color:#878787;"></div>
    <div id="obtuseresult"style="position:absolute;top:70%;left:30%;font-size:20px;color:#878787;"></div>
    <div id="stepfine"style="position:absolute;top:75%;left:30%;font-size:20px;color:#878787;"></div>
</div>

<p id="heading19"style="position:absolute;top:-1%;left:30%;font-size:28px;color:blue;">Different types of triangle in angle method.</p>
</body>
</html>

我想通过在请求标头中传递参数来控制每页中要打印的记录数,如下所示:

curl -b cookies.txt -X POST http://localhost:8081/test/api/v1.0/docs_page/1 -H'max_per_page:4'-H'Content-type:application / json'

@app.route('/test/api/v1.0/docs_page/<int:page>', methods=['POST'])
def search_docs_page(page):
    if 'id' in session:
        doc_list = []
        no_of_pgs = 0
        doc_list = common_search_code()
        # doc_list is a resultset after querying the table for a set of query condition  
        header_dict = dict(request.headers)
        for i in header_dict.items():
            if i == 'Max-Per-Page':
                max_per_pg = int(header_dict[i])
        no_of_pgs = len(doc_list) / max_per_pg
        print 'number of doc: ' + str(len(doc_list))
        print 'number of pages: ' +  str(no_of_pgs)
        print 'max per page:' + str(max_per_pg)
        print 'page number: '+ str(page)
        page = int(request.args.get(page, type=int, default=1))
        pagination = Pagination(page=page,
                                total=len(doc_list),
                                search=True, record_name='documents')

        return jsonify({'pagination': list(pagination.__dict__),
                        'doc_list': doc_list}), 200

    return jsonify({'message': "Unauthorized"}), 401

1 个答案:

答案 0 :(得分:2)

目前,我已对上述代码进行了更改,以此方式工作:

@app.route('/test/api/v1.0/docs_page2', methods=['POST'])
def search_docs_page2():
    if 'id' in session:
        docs = []
        no_of_pgs = 0
        header_dict = dict(request.headers)
        for k in header_dict:
            print header_dict[k], 'key', k
        if 'Max-Per-Page' in header_dict.keys():
            max_per_pg = int(header_dict['Max-Per-Page'])
            page_no = int(request.headers.get('page_no', type=int, default=1))
            offset1 = (page_no - 1) * max_per_pg
            query1 = common_search_code()
            s = query1.limit(max_per_pg).offset(offset1)
            rs = conn.execute(s)
            for r in rs:
                docs.append(dict(r))
            # no_of_pgs = float(len(doc_list) / float(max_per_pg))
            no_of_pgs = float(len(docs) / float(max_per_pg))
            no_of_pgs = int(math.ceil(no_of_pgs))
            print 'number of doc: ' + str(len(docs))
            print 'number of pages: ' +  str(no_of_pgs)
            print 'max per page:' + str(max_per_pg)
            # docs.append(doc_list[offset:(offset + max_per_pg)])
            return jsonify({'docs': docs,
                            'no_of_pages': str(no_of_pgs)}), 200

        return jsonify({'message': "Max. per page not specified"}), 400

    return jsonify({'message': "Unauthorized"}), 401

相同的卷曲:

curl -b cookies.txt  -X POST http://localhost:8081/test/api/v1.0/docs_page2 -H 'max_per_page:4' -H 'Content-type:application/json' -H 'page_no:2'