zoukankan      html  css  js  c++  java
  • sqlalchemy--group_concat的使用

    今天,一个app客户端同事需要我服务器端提供一组数据,这组数据要按类分好,把整个结构都展示给他,他直接使用就可以了。数据大概如下面这种:

    sqlalchemy,group,concat

    同事需要的结构大概就是类型1有多少,分别是什么;类型2有多少,分别是什么,,以此类推。本来我想一股脑全部给他,每个数据都有个字段device_type,你自己去解析分类一下,但客户端同事说,在客户端做这种事,浪费时间,客户响应会变慢,所以要我们服务器端来做。我们服务器端做,最好不要自己去解析,不然一样慢,最好一条sql语句,自动为我解析好。

    如果熟悉mysql,应该可以知道,可以用group_concat进行分组。

    先用sql语句查询一下,会有如下结果;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    mysql> select device_type, group_concat(id) from otherequipment group by device_type;
    +-------------+---------------------+
    | device_type | group_concat(id)    |
    +-------------+---------------------+
    |           1 | 1,11,9,13,6,5,4,3,2 |
    |           2 | 10,12               |
    |           3 | 8,7                 |
    +-------------+---------------------+
    3 rows in set (0.00 sec)


    按照类型划分设备,对比一下上面的数据,是不是一下子全出来了。

    但在sqlalchemy中如何使用呢?sqlalchemy有个func,里面包含各种sql函数。我们试用一下吧。

    sqlalchemy的model如下,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class OtherEquipment(Base):
        """
        其他公司普通设备
        """
        __tablename__ = 'otherequipment'
     
        id = Column('id', Integer, primary_key=True)
        device_type = Column('device_type', SmallInteger, index=True, default=1)
     
        name = Column('name', String(40), index=True)
        position = Column('position', String(40), nullable=True)


    那获取这些设备的对象就很好写咯,

    1
    2
    3
    4
    5
    6
    7
    es = db_session.query(OtherEquipment.device_type, func.group_concat(OtherEquipment.id)).group_by(OtherEquipment.device_type).all()
    all_equipments = []
    for l in es:
        device_type, ids = l
        ids = ids.split(',')
        equipments = [OtherEquipment.query.get(e_id) for e_id in ids]
        all_equipments.append((device_type, equipments))


    all_equipments就是其所有设备的结构图,打印一下,结果如下:

    1
    [(1, [外部设备1, 外部设备11, 外部设备9, 外部设备13, 外部设备6, 外部设备5, 外部设备4, 外部设备3, 外部设备2]), (2, [外部设备10, 外部设备12]), (3, [外部设备8, 外部设备7])]

    # 除此之外:


    CREATE AGGREGATE group_concat_string(anyelement)
    (
    sfunc = array_append, -- 每行的操作函数,将本行append到数组里
    stype = anyarray, -- 聚集后返回数组类型
    initcond = '{}' -- 初始化空数组
    );

    在数据库中执行上面的sql语句,函数group_concat_string才起作用,

    例如:

    g.session.query(func.group_concat_string(Student.score)).all()

    获取所有男生的人数(和group_by 相似,group_by分组统计个数,group_concat_string分组每组详情)

    CREATE AGGREGATE public.FIRST (
    sfunc = public.first_agg,
    basetype = anyelement,
    stype = anyelement
    )

    这样,客户端直接拿到接口的数据,就可以直接展示,不需要自己轮询,再去分析了。

  • 相关阅读:
    面向对象的测试用例设计有几种方法?如何实现?
    html5直接调用手机相机照相/录像
    关于ionic2在IOS上点击延迟的问题
    vue项目使用html5+ barcode扫码在苹果遇到的问题以及自己的解决方法
    vue设置多个入口
    把项目中的vant UI组件升级
    记录axios在IOS上不能发送的问题
    getElementsByClassName兼容 封装
    记录vue用 html5+做移动APP 用barcode做扫一扫功能时安卓 的bug(黑屏、错位等等)和解决方法
    JS的事件委托
  • 原文地址:https://www.cnblogs.com/zknublx/p/8717752.html
Copyright © 2011-2022 走看看