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

如何在Python中通过for循环批量实现MySQL游标查询并解决语法错误?

如何用Python循环批量实现MySQL多站点数据查询(解决exec语法错误)

问题背景

你原本通过创建多个独立游标来查询不同站点的平均IWV数据,代码可以正常运行,但当需要查询更多站点时,想用循环简化代码,尝试用exec动态创建游标和变量却遇到了语法错误:

exec(cursor{m} = db.cursor()) ^ SyntaxError: invalid syntax

你的原始尝试代码:

for m in range(1,5):
    exec(f'cursor{m} = db.cursor()')
for n in range(1,5):
    for stat in range(51,55):
        exec(f'sql_select_AVG{n} = "SELECT AVG(IWV) As AverageIWV FROM GNSS_OUT WHERE StationID={stat} AND Datetime BETWEEN \'2021-05-01\' AND \'2021-05-31\' AND SourceGpsID=23 ;"')
        exec(f'cursor{n}.executemany(sql_select_AVG{n})')
        exec(f'yaxis{n}=cursor{n}.fetchall()')

错误原因

虽然你用了f-string,但exec动态创建变量本身就是不推荐的实践——不仅容易出现语法细节错误(比如字符串转义、变量名冲突),还会让代码难以调试和维护。而且你的代码里还有逻辑问题:内层循环多次给同一个sql_select_AVG{n}赋值,最后只会保留最后一个站点的查询语句,完全达不到批量查询的目的。

正确解决方案

我们可以用列表/字典来管理游标和查询结果,既避免动态变量的问题,又让代码更简洁高效。下面提供两种方案:

方案一:循环逐个查询站点(适合需要单独处理每个站点的场景)

# 定义需要查询的站点ID列表
station_ids = list(range(51, 55))  # 对应51、52、53、54四个站点
query_results = []

# 循环处理每个站点
for station_id in station_ids:
    # 创建游标
    cursor = db.cursor()
    # 使用参数化查询,避免SQL注入,同时简化字符串拼接
    sql = """
        SELECT AVG(IWV) AS AverageIWV 
        FROM GNSS_OUT 
        WHERE StationID = %s 
          AND Datetime BETWEEN '2021-05-01' AND '2021-05-31' 
          AND SourceGpsID = 23
    """
    # 执行查询,传入站点ID作为参数
    cursor.execute(sql, (station_id,))
    # 获取结果:fetchone()返回单个元组,取第一列就是平均IWV
    avg_iwv = cursor.fetchone()[0]
    # 将结果存入列表,保留站点ID和对应值
    query_results.append({
        "station_id": station_id,
        "average_iwv": avg_iwv
    })
    # 关闭游标,释放资源
    cursor.close()

# 输出结果
for result in query_results:
    print(f"站点 {result['station_id']} 的平均IWV: {result['average_iwv']}")

方案二:单SQL批量查询所有站点(更高效,减少数据库交互)

如果不需要单独处理每个站点的查询过程,推荐用IN子句+分组查询,一次获取所有站点的结果,效率更高:

station_ids = list(range(51, 55))
# 构造批量查询的SQL,用IN子句匹配所有站点ID,按StationID分组计算平均值
sql_template = """
    SELECT StationID, AVG(IWV) AS AverageIWV 
    FROM GNSS_OUT 
    WHERE StationID IN (%s) 
      AND Datetime BETWEEN '2021-05-01' AND '2021-05-31' 
      AND SourceGpsID = 23
    GROUP BY StationID
"""
# 生成对应数量的占位符(比如4个站点就生成"%s, %s, %s, %s")
placeholders = ", ".join(["%s"] * len(station_ids))
# 替换模板中的占位符
final_sql = sql_template % placeholders

cursor = db.cursor()
# 执行查询,传入站点ID列表作为参数
cursor.execute(final_sql, station_ids)
# 获取所有结果
query_results = cursor.fetchall()

# 输出结果
for station_id, avg_iwv in query_results:
    print(f"站点 {station_id} 的平均IWV: {avg_iwv}")

cursor.close()

关键注意事项

  1. 避免使用exec动态创建变量:用列表、字典等容器来管理数据,代码更易读、易调试。
  2. 使用参数化查询:不要直接把变量拼接到SQL字符串里,防止SQL注入风险,同时避免字符串转义的麻烦。
  3. 及时关闭游标:用完游标后记得调用close(),释放数据库资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 12:13:13