You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQLAlchemy:如何将单条多实体查询结果序列化为带列名的JSON

问题描述

我编写了如下SQLAlchemy数据库查询代码:

get_user_details = (
    self.db_session.query(
        users_table.firstname,
        users_table.lastname,
        users_table.profile_pic,
        users_table.email,
    )
    .filter(users_table.userid == user_payload["userid"])
    .first()
)

打印get_user_details时得到的是值元组,但我需要获取以列名为键的键值对形式的JSON输出。目前我已经有一个处理特殊类型的序列化函数:

def alchemyencoder(obj):
    """JSON encoder function for SQLAlchemy special classes."""
    if isinstance(obj, datetime.date):
        return obj.isoformat()
    elif isinstance(obj, decimal.Decimal):
        return float(obj)
    elif isinstance(obj, datetime.time):
        return obj.strftime("%H:%M")

请问该如何实现这一需求?

解决方案

这里有几个简单有效的方法,帮你把查询结果转换成带列名的键值对,再结合你现有的alchemyencoder生成符合要求的JSON:

方法一:用SQLAlchemy自带的方法快速转字典

你当前查询返回的get_user_detailsKeyedTuple类型(SQLAlchemy专门为指定列查询设计的类型),它自带一个_asdict()方法,能直接把结果转换成以列名为键的字典:

user_dict = get_user_details._asdict()

拿到这个字典后,直接用json.dumps配合你的编码器就能生成JSON了:

import json

json_result = json.dumps(user_dict, default=alchemyencoder)

这个方法最省事,完全不需要额外的手动映射。

方法二:手动构造字典(适合自定义键名的场景)

如果你想修改输出的键名(比如把firstname改成first_name),或者需要对某些字段做临时处理,可以手动把列名和对应值配对:

# 定义你想要的键名列表,和查询列的顺序保持一致
column_keys = ["firstname", "lastname", "profile_pic", "email"]
user_dict = dict(zip(column_keys, get_user_details))

同样,后续用json.dumpsalchemyencoder序列化即可。

方法三:通用转换函数(适合频繁转换的场景)

如果你的项目里经常需要把SQLAlchemy查询结果转成字典,可以写一个通用工具函数,顺便把你的alchemyencoder逻辑整合进去:

def sqlalchemy_row_to_dict(row):
    """将SQLAlchemy查询行转换为带列名的字典,自动处理特殊数据类型"""
    result_dict = {}
    # 遍历查询结果的所有列
    for col in row.keys():
        value = getattr(row, col)
        # 用你的编码器处理特殊类型,空值直接保留
        result_dict[col] = alchemyencoder(value) if value is not None else value
    return result_dict

# 使用示例
user_dict = sqlalchemy_row_to_dict(get_user_details)
json_result = json.dumps(user_dict)

这个函数对KeyedTuple和完整的实体对象都适用,通用性很强。

内容的提问来源于stack exchange,提问作者Jithin Zacharia

火山引擎 最新活动