You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将SQL查询初始化为dataclass时如何避免get_fields函数硬编码问题

我们的目标是基于对字段的人工分类得到SQL中需要查询的列,示例代码如下:

from dataclasses import dataclass

@dataclass
class Q:
    fruits = ('taste', 'color', 'shine')
    vege = ('is_green', 'color', 'juiceable')
    meat = ('is_white', 'is_dark', 'is_red', 'meat_name')
    carbs = ('is_refined', 'gi')

    @staticmethod
    def get_fields(self, add_fruits=False, add_vege=False, add_meat=False, add_carbs=False):
         fields = set()
         fields.update(self.fruits) if add_fruits else None
         fields.update(self.vege) if add_vege else None
         fields.update(self.meat) if add_meat else None
         fields.update(self.carbs) if add_carbs else None
         return ",".join(sorted(fields))

print(f"SELECT {Q.get_fields(add_fruits=True, add_vege=True)} from food_features")

注:原示例代码存在两处可优化的小问题:一是@staticmethod不需要接收self参数,要访问类属性建议改用@classmethod;二是原代码对join后的字符串做sorted会把字符串拆成单个字符列表,此处已修正为仅对字段列表排序后再拼接。

当Q类中存在大量字段分类时,如何避免在.get_fields函数中硬编码如下逻辑?

fields.update(self._field_name_) if add_field_name else None 

解决方案

方案1:自动匹配add_前缀参数(兼容原有调用方式)

无需修改现有调用逻辑,新增分类时仅需要在Q类中新增对应属性即可,不需要改动get_fields代码:

from dataclasses import dataclass

@dataclass
class Q:
    fruits = ('taste', 'color', 'shine')
    vege = ('is_green', 'color', 'juiceable')
    meat = ('is_white', 'is_dark', 'is_red', 'meat_name')
    carbs = ('is_refined', 'gi')
    # 后续新增分类直接在这里加属性即可,不用改get_fields
    # snack = ('is_salty', 'is_sweet', 'calorie')

    @classmethod
    def get_fields(cls, **kwargs):
        fields = set()
        # 遍历所有关键字参数,匹配add_前缀的参数
        for param_name, is_add in kwargs.items():
            if param_name.startswith('add_') and is_add:
                # 去掉add_前缀得到对应的分类属性名
                category = param_name[4:]
                # 从类中取出对应分类的字段列表加入集合
                if hasattr(cls, category):
                    fields.update(getattr(cls, category))
        return ",".join(sorted(fields))

# 原有调用方式完全兼容
print(f"SELECT {Q.get_fields(add_fruits=True, add_vege=True)} from food_features")
# 新增分类后直接传对应参数即可
# print(f"SELECT {Q.get_fields(add_snack=True, add_meat=True)} from food_features")

方案2:直接传入分类列表(调用更简洁)

如果可以调整调用方式,直接传入需要的分类名称列表,代码逻辑更清晰易懂:

from dataclasses import dataclass

@dataclass
class Q:
    fruits = ('taste', 'color', 'shine')
    vege = ('is_green', 'color', 'juiceable')
    meat = ('is_white', 'is_dark', 'is_red', 'meat_name')
    carbs = ('is_refined', 'gi')

    @classmethod
    def get_fields(cls, categories: list):
        fields = set()
        for cate in categories:
            if hasattr(cls, cate):
                fields.update(getattr(cls, cate))
        return ",".join(sorted(fields))

# 调用时直接传入需要的分类列表
print(f"SELECT {Q.get_fields(categories=['fruits', 'vege'])} from food_features")

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 19:06:04