• flask_sqlalchemy 查询结果转dict 终极解决方案


      之前为了学习Python,试着拿Flask作框架搞小网站,感觉还不错,基本就抛弃了PHP。前段时间做了一个微信小程序,想着yii框架拿来写几十个小接口是不是浪费了,就继续用flask写api了,哪想到填坑无数啊。

      Python的ORM框架就属Sqlalchemy牛逼,网上资料也多,想着和yii里面应该差不多,就拿来用了。第二天万万没想到,php里面简单的一句asArray就能解决的问题,flask_sqlalchemy居然没有解决方案,查询的结果对象无法直接JSON序列化。这期间从南到北地找,大部分解决方案都是做一个JSON.dumps的Encoder方法,来转化restult对象,无意中看见https://www.cnblogs.com/wancy86/p/6421792.html 这个帖子,说queryresult对象加入了json属性,欣喜万分,搞了一晚上也没找到这个方法。

      原文链接:https://www.cnblogs.com/eating-gourd/p/9997751.html


    咳咳,正文:  

      网上的方法主要问题在于只能处理result对象或model对象之一,当查询某个表全部字段时,如

    1 db.session.query(User).filter().all()

      其返回User这个类的对象列表,而查询某些字段或者多表连接时,如:

     1 db.session.query(User.UserID,User.UserName).filter().all() 

      其返回result对象的列表,这两种情况下,对象的属性不同,导致很多情况下只能适应一种返回。今天趁闲着没事,把两种情况的查询结果转dict作了一下整理,封装为一个queryToDict函数,并同时支持all()返回的列表和first()返回的单个对象结果:

    from datetime import datetime as cdatetime #有时候会返回datatime类型
    from datetime import date,time
    from flask_sqlalchemy import Model
    from sqlalchemy.orm.query import Query
    from sqlalchemy import DateTime,Numeric,Date,Time #有时又是DateTime
    
    def queryToDict(models):
        if(isinstance(models,list)):
            if(isinstance(models[0],Model)):
                lst = []
                for model in models:
                    gen = model_to_dict(model)
                    dit = dict((g[0],g[1]) for g in gen)
                    lst.append(dit)
                return lst
            else:
                res = result_to_dict(models)
                return res
        else:
            if (isinstance(models, Model)):
                gen = model_to_dict(models)
                dit = dict((g[0],g[1]) for g in gen)
                return dit
            else:
                res = dict(zip(models.keys(), models))
                find_datetime(res)
                return res
    #当结果为result对象列表时,result有key()方法
    def result_to_dict(results):
        res = [dict(zip(r.keys(), r)) for r in results]
        #这里r为一个字典,对象传递直接改变字典属性
        for r in res:
            find_datetime(r)
        return res
    def model_to_dict(model):      #这段来自于参考资源
        for col in model.__table__.columns:
            if isinstance(col.type, DateTime):
                value = convert_datetime(getattr(model, col.name))
            elif isinstance(col.type, Numeric):
                value = float(getattr(model, col.name))
            else:
                value = getattr(model, col.name)
            yield (col.name, value)
    def find_datetime(value):
        for v in value:
            if (isinstance(value[v], cdatetime)):
                value[v] = convert_datetime(value[v])   #这里原理类似,修改的字典对象,不用返回即可修改
    def convert_datetime(value):
        if value:
            if(isinstance(value,(cdatetime,DateTime))):
                return value.strftime("%Y-%m-%d %H:%M:%S")
            elif(isinstance(value,(date,Date))):
                return value.strftime("%Y-%m-%d")
            elif(isinstance(value,(Time,time))):
                return value.strftime("%H:%M:%S")
        else:
            return ""
    dit = dict((g[0],g[1]) for g in gen)相关代码也是之前查找资料获得,现在找不到出处了,作者可以联系我。
     滚去学雅思了,代码写得较快,欢迎指出bug

    参考资源:

    [1] https://stackoverflow.com/questions/5022066/how-to-serialize-sqlalchemy-result-to-json

    [2] https://segmentfault.com/q/1010000007459402/a-1020000007460322

    我就是我,吃瓜的瓜
  • 相关阅读:
    Mysql数据库改名
    查看数据库大小或者表大小
    Bootstarp 水平垂直居中
    Java Collection.sort 排序升序, 降序问题
    Mysql 函数, 存储过程, 任务调度
    Mysql 日期类型 date、datetime、timestamp.
    Mysql 获取当天,昨天,本周,本月,上周,上月的起始时间
    Mysql 事件event_scheduler是OFF
    Java 文件读取
    Spring cron 定时调度配置
  • 原文地址:https://www.cnblogs.com/eating-gourd/p/9997751.html
Copyright © 2020-2023  润新知