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

如何基于JSON随机输入调用多个函数并执行SQL查询

解决方案

一、业务代码调整(支持动态JSON输入、多函数统一调度)

原有aaa()、bbb()逻辑重复,我们直接抽离公共配置,既不需要重复写相似函数,也支持外部传入随机JSON数组作为输入:

import json
import random
# 替换为你实际依赖的导入路径
from your_module import DatabaseConnection, HttpRequest, api_key, database_date_column

# 原有aaa、bbb的静态配置抽离,新增同类逻辑仅需加配置项即可
TASK_CONFIG = {
    "aaa": [{'code': 'XXX', 'database_column': 'aaa_1'}, {'code': 'YYY', 'database_column': 'aaa_2'}],
    "bbb": [{'code': 'ZZZ', 'database_column': 'bbb_1'}, {'code': 'UUU', 'database_column': 'bbb_2'}]
}

def daily(custom_config: dict = None):
    """
    主入口函数,支持传入自定义随机配置,不传则使用默认静态配置
    :param custom_config: 格式与TASK_CONFIG一致
    """
    db_connection = DatabaseConnection()
    task_config = custom_config if custom_config else TASK_CONFIG
    
    # 统一调度所有配置对应的任务,不需要单独调用aaa、bbb
    for table_name, symbols_list in task_config.items():
        load_data_from_api_to_database(db_connection, table_name, symbols_list)

    return {'success': True}


def load_data_from_api_to_database(db_connection, database_table, symbols_list):
    http_request = HttpRequest()
    for _, symbol in enumerate(symbols_list):
        code = symbol['code']
        database_column = symbol['database_column']

        response = http_request.get(
            f'https://api.example.com/value/{code}', 
            headers={'accept': 'application/json', 'appkey': api_key}
        )

        # 单个请求失败跳过,不终止后续其他任务,比直接return更合理
        if response.status_code != 200:
            continue
        try:
            json_data = json.loads(response.text)
        except json.JSONDecodeError:
            continue

        data_points = json_data.get('dataPoint', [])
        for point in data_points:
            value = point['value']
            date = point['date']
            db_connection.execute(
                f'INSERT INTO "{database_table}" ("{database_date_column}") VALUES (%(date_time)s) ON CONFLICT ("{database_date_column}") DO NOTHING', 
                {'date_time': date}
            )
            db_connection.execute(
                f'UPDATE "{database_table}" SET "{database_column}" = %(value)s WHERE "{database_date_column}" = %(date_time)s', 
                {'value': value, 'date_time': date}
            )
        db_connection.commit()

随机JSON输入生成示例

需要随机输入时直接生成自定义配置传入daily即可:

def generate_random_config(task_count=2, symbol_per_task=2):
    random_config = {}
    for i in range(task_count):
        table_name = f"test_table_{random.randint(1,100)}"
        symbols = []
        for j in range(symbol_per_task):
            symbols.append({
                "code": ''.join(random.choices('ABCDEFGHIJKLMNOPQRSTUVWXYZ', k=3)),
                "database_column": f"test_col_{random.randint(1, 10)}"
            })
        random_config[table_name] = symbols
    return random_config

# 调用示例:传入随机配置执行业务逻辑
# daily(custom_config=generate_random_config())

二、测试代码修正(从daily入口测试)

原有测试存在函数名不规范、语法错误、方法调用匹配错误的问题,修正后如下:

import unittest
from unittest.mock import patch
import re
import json
# 替换为你实际的函数导入路径
from src.daily_handler import daily, TASK_CONFIG, generate_random_config, api_key

class TestDailyHandler(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # 模拟HTTP请求
        cls.mock_get_patcher = patch('src.daily_handler.HttpRequest.get')
        cls.mock_get = cls.mock_get_patcher.start()
        cls.mock_get.return_value.status_code = 200
        cls.mock_get.return_value.text = json.dumps({
            "dataPoint": [
                {"value": random.randint(1,100), "date": "2024-01-01"},
                {"value": random.randint(1,100), "date": "2024-01-02"}
            ]
        })
        # 模拟数据库连接
        cls.mock_db_patcher = patch('src.daily_handler.DatabaseConnection')
        cls.mock_db = cls.mock_db_patcher.start()
        cls.mock_db_instance = cls.mock_db.return_value

    @classmethod
    def tearDownClass(cls):
        cls.mock_get_patcher.stop()
        cls.mock_db_patcher.stop()

    def test_daily_with_default_config(self):
        # 直接从主入口调用测试
        result = daily()
        self.assertEqual(result, {'success': True})

        # 校验接口调用符合预期
        all_symbols = []
        for symbols in TASK_CONFIG.values():
            all_symbols.extend(symbols)
        expected_calls = [
            unittest.mock.call(
                f'https://api.example.com/value/{s["code"]}', 
                headers={'accept': 'application/json', 'appkey': api_key}
            ) for s in all_symbols
        ]
        self.mock_get.assert_has_calls(expected_calls, any_order=True)

        # 校验SQL执行符合预期
        execute_calls = self.mock_db_instance.execute.call_args_list
        insert_count = len([c for c in execute_calls if re.search(r'INSERT INTO ', str(c), re.IGNORECASE)])
        update_count = len([c for c in execute_calls if re.search(r'UPDATE ', str(c), re.IGNORECASE)])
        self.assertEqual(insert_count, update_count)
        # 每个symbol处理完提交一次,commit次数等于symbol总数
        self.assertEqual(self.mock_db_instance.commit.call_count, len(all_symbols))

    def test_daily_with_random_config(self):
        # 测试随机输入场景
        random_config = generate_random_config(task_count=3, symbol_per_task=2)
        result = daily(custom_config=random_config)
        self.assertEqual(result, {'success': True})

        all_symbols = []
        for symbols in random_config.values():
            all_symbols.extend(symbols)
        self.assertEqual(self.mock_get.call_count, len(all_symbols))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:45:04