flask-sqlalchemy的paginate源码分析

简介: 今天遇到一个问题,用flask-sqlalchemy的paginate做分页的时候,发现联表查询时分页出来结果数据少了很多,直接all()出来就没问题,把sql单独执行发现是联表查时有重复数据,group一下就好了,但是all()结果没有重复的,all()还给滤重了?而且paginate还是在滤重前做的limit,所以去重后结果就少了,而且还影响了total的值,趁这个机会看一下flask-sqlalchemy的源码吧

今天遇到一个问题,用flask-sqlalchemy的paginate做分页的时候,发现联表查询时分页出来结果数据少了很多,直接all()出来就没问题,把sql单独执行发现是联表查时有重复数据,group一下就好了,但是all()结果没有重复的,all()还给滤重了?而且paginate还是在滤重前做的limit,所以去重后结果就少了,而且还影响了total的值,趁这个机会看一下flask-sqlalchemy的源码吧

class BaseQuery(orm.Query):
    def paginate(self, page=None, per_page=None, error_out=True, max_per_page=None, count=True):
        """
        当“error_out”为"True"时,符合下面判断时将引起404响应,我一般都关了这个
        error_out,把接口返回什么的控制权拿回来。
        """
        //如果"page"或"per-page"是"None",则将从请求查询
        //flask-sqlalchemy和flask app绑定的还真是挺深,连request都用上了
        if request:
            if page is None:
                try:
                    //这么写更好page = request.args.get('page', 1, type=int)
                    page = int(request.args.get('page', 1))
                except (TypeError, ValueError):
                    if error_out:
                        abort(404)

                    page = 1

            if per_page is None:
                try:
                    per_page = int(request.args.get('per_page', 20))
                except (TypeError, ValueError):
                    if error_out:
                        abort(404)

                    per_page = 20
        else: // 如果没有请求分别默认为1和20
            if page is None:
                page = 1
            if per_page is None:
                per_page = 20
        //如果指定了“max_per_page”,则“per_page”将受这个值钳制。
        if max_per_page is not None:
            per_page = min(per_page, max_per_page)

        if page < 1:
            ......
                page = 1

        if per_page < 0:
            ......
                per_page = 20
        //原来paginate就是用的limit和offset,我猜如果有重复数据,先limit后all,all的时候再去个重,数据就少了,分页也没了
        items = self.limit(per_page).offset((page - 1) * per_page).all()
        ......
        //如果"count"是"False",total就不能用了,不用的时候可以关掉,省个查询
        if not count:
            total = None
        else:
            //为什么order_by(None)?
            total = self.order_by(None).count()

        return Pagination(self, page, per_page, total, items)

class Pagination(object):
    def __init__(self, query, page, per_page, total, items):
        #: the unlimited query object that was used to create this
        #: pagination object.
        self.query = query
        #: the current page number (1 indexed)
        self.page = page
        #: the number of items to be displayed on a page.
        self.per_page = per_page
        #: the total number of items matching the query
        self.total = total
        #: the items for the current page
        self.items = items
    ......

flask-sqlalchemy代码没有去重,再看看sqlalchemy的代码

class Query(Generative):
    ......
    def all(self):
        """
        不翻译了,留着原话,这里给去重了
        Return the results represented by this :class:`_query.Query`
        as a list.
        This results in an execution of the underlying SQL statement.
        .. warning::  The :class:`_query.Query` object,
           when asked to return either
           a sequence or iterator that consists of full ORM-mapped entities,
           will **deduplicate entries based on primary key**.  See the FAQ for
           more details.
            .. seealso::
                :ref:`faq_query_deduplicating`
        """
        return self._iter().all()
    ......

到此,可知sqlalchemy的all()操作是去重了的

参考
https://github.com/pallets/flask-sqlalchemy
https://github.com/sqlalchemy/sqlalchemy

相关文章
|
8月前
|
Python
扒源码 - 一个请求在flask中经历了什么
客户端发起一个请求,Flask 都干了什么呢?url 如何与视图进行绑定的?
|
12月前
|
存储 小程序 关系型数据库
python微信小程序看图猜成语源码flask
启动Idiom/flask下的venv虚拟环境,运行python manage.py runserver命令启动Flask。然后打开微信开发者工具并扫码登录,选择flask/weapp-idiom小程序,加载完成后进入小程序登录页面,
165 0
|
设计模式 对象存储 Python
【flask高级】从源码深入理解flask的应用上下文和请求上下文
之前在flask入门系列中大概写了flask的应用上下文和请求上下文,比较浅显,但我们后面要了解flask的运行机制,就必须先深入了解一下flask中的应用上下文和请求上下文,这节阿牛将继续带你从源码来剖解他的奥秘!
123 0
【flask高级】从源码深入理解flask的应用上下文和请求上下文
|
Python
Flask 源码阅读-下篇 |Python 主题月
flask项目大名鼎鼎,不需要多做介绍。我把它称之为python服务开发的TOP2项目,另外一个就是django。这两个项目各有千秋,各自有不同的应用场景,都需要深入理解,熟练掌握。本次源码选择的版本是 1.1.2,我会采用慢读法,尽自己最大努力把它讲透。
171 0
|
编解码 Python
Python 技术篇 - 修改源码解决中文主机名导致的flask、socket服务起不来问题: ‘utf-8‘ codec can‘t decode byte 0xc0 in position...
Python 技术篇 - 修改源码解决中文主机名导致的flask、socket服务起不来问题: ‘utf-8‘ codec can‘t decode byte 0xc0 in position...
301 0
Python 技术篇 - 修改源码解决中文主机名导致的flask、socket服务起不来问题: ‘utf-8‘ codec can‘t decode byte 0xc0 in position...
|
Python Go 前端开发
源码解析flask的路由系统
当我们新建一个flask项目时,pycharm通常已经为项目定义了一个基本路由 @app.route('/') def hello_world(): return 'Hello World!' 此时在浏览器中输入地址http://127.
903 0
|
JSON 数据格式 Python
源码解析Flask的配置文件
在flask里,我们常在主文件中定义某些配置,比如: app.debug = True app.secret_key = 'helloworld!!' 实际上,flask中默认可以进行可选的配置项有很多。
916 0
|
Web App开发 前端开发 关系型数据库
python+flask+html/css+mysql+BAE 打造CSDN简历自动生成系统(附网站完全源码)
1.背景        一直想自己动手写个web app玩玩,前几天看了一个github的resume自动生成的web-app,所以就动手仿造了一个csdn的简历生成器。结构很简单,前端是html/css文件(这个模仿了github的那个网页,因为博主不太懂前端)。后台是一个爬虫软件,可以把csdn的个人信息爬下来,然后显示出来,最后部署到了百度云。百度的云数据库,真是坑爹.......,我
2067 0
|
25天前
|
JSON API 数据格式
构建RESTful APIs:使用Python和Flask
【4月更文挑战第9天】本文介绍了如何使用Python的Flask框架构建RESTful API。Flask是一个轻量级的Web应用框架,适合小型项目和微服务。首先,确保安装了Python和Flask,然后通过创建基本的Flask应用开始。接着,定义资源和路由,例如为“图书”资源创建GET、POST、PUT和DELETE方法的路由。使用`request`对象处理客户端数据,`jsonify`生成JSON响应。错误处理通过返回错误信息和相应HTTP状态码完成。最后,运行并测试API,发现Flask提供了一种简单高效的方式来构建RESTful APIs。
|
25天前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
【4月更文挑战第9天】本文对比了Python三大Web框架Django、Flask和Pyramid。Django功能全面,适合快速开发,但学习曲线较陡;Flask轻量灵活,易于入门,但默认配置简单,需自行添加功能;Pyramid兼顾灵活性和可扩展性,适合不同规模项目,但社区及资源相对较少。选择框架应考虑项目需求和开发者偏好。