请教问题。Flask 中用 SQLAlchemy 查询多表对象未指定列或其中一表未指定列时,如何把查询结果转为 Json

2020-10-29 10:50:26 +08:00
 luxiaoer

代码片段

# 表
class ProductCheckBillMod(Base):
    __tablename__ = 'sc_product_check'
    id = Column(Integer, primary_key=True)
    bill_no = Column(String)

class ProductCheckBillMod(Base):
    __tablename__ = 'sc_product_check_detail'
    id = Column(Integer, primary_key=True)

# 查询 

task_obj = db.session.query(*DBModels).join(*joins).filter(*filters).order_by(*orderbys).slice((page_index - 1) * page_size,page_index * page_size).all()

情况 1 DBModels = [ProductCheckBillMod,ProductCheckBillMod]

情况 2 DBModels = [ProductCheckBillMod.id,ProductCheckBillMod.bill_no,ProductCheckBillMod]

在以上的两种情况下 task_obj 如何转 json

以下这段查询结果转 dict 是 Copy 的,稍微改动过



def queryToDict(models,fsModel=None):
    if fsModel == None:
        fsModel = Model
    if isinstance(fsModel,list):
        fsModel=fsModel[0]
    if (isinstance(models, list)):
        if not len(models):
            return []
        if (isinstance(models[0], fsModel)):
            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, fsModel)):
            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):
    pass

def convert_datetime(value):
    pass

1862 次点击
所在节点    Python
5 条回复
18870715400
2020-10-29 15:02:59 +08:00
应该不是转换成 json 应该是字典吧
如果是.all()的结果
[dict((col.name, getattr(obj, col.name)) for col in obj.__table__.columns) for obj in objs]


如果是.first()的结果
dict((col.name, getattr(objs, col.name)) for col in objs.__table__.columns)
luxiaoer
2020-10-29 17:37:44 +08:00
@18870715400
感谢回复,我查询后的 task_obj 是一个 result 对象,尝试使用时提示
AttributeError: 'result' object has no attribute '__table__'
18870715400
2020-10-29 21:46:56 +08:00
@luxiaoer 我 使用的是 sqlalchemy 同样都是转换成 字典, 你可以 dir 一下看一下应该有类似的方法, 或者直接去官方文档看一下应该有
https://www.cnblogs.com/eating-gourd/p/9997751.html 参考
luxiaoer
2020-10-30 16:05:02 +08:00
@18870715400 是的,我的核心代码部分就是 copy 的这部分。
已解决
luxiaoer
2020-10-30 16:06:36 +08:00
回车快了,贴下解决代码部分

重写了 result_to_dict 函数,希望可以帮到其他小伙伴
# 当结果为 result 对象列表时一般为多表或多列查询结果
def result_to_dict(results):
res=[]
for result in results:
row_d = dict()
for attr in dir(result):
if(not attr.startswith('_') and attr not in ['count','index','keys']):
value = getattr(result, attr)
if "_sa_instance_state" in dir(value):# 通过 dir 中是否含有_sa_instance_state 判定是否为 Model 类
gen = model_to_dict(value)
dit = dict((g[0], g[1]) for g in gen)
row_d.update(dit) # 更新到行字典中
else:
row_d[attr] = getattr(result, attr) # 通过 getattr 获取值添加到字典
res.append(d)
for r in res:
find_datetime(r)
return res

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/719702

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX