使用PyMySQL查询游戏ID列表并复用ID查询详情时的格式问题排查
使用PyMySQL查询游戏ID列表并复用ID查询详情时的格式问题排查
看起来你遇到的核心问题是没处理好PyMySQL查询结果的格式,导致后续用ID查询时完全匹配不上,所以才会返回空结果。我来一步步帮你梳理和解决:
为什么你的gameIds是((4,), (5,), ...)这种格式?
PyMySQL的cur.fetchall()返回的是查询结果的所有行,每一行都是一个元组——哪怕你只查了一个字段(比如gameId),每一行也会是包含这个字段值的单元素元组。所以你遍历gameIds时,拿到的id其实是(4,)这样的元组,而不是单独的整数4。
问题出在哪里?
你原来的代码里直接把这个元组拼到SQL里:
list_sql = f"SELECT * FROM Games WHERE gameId = '{id}'"
这会生成类似WHERE gameId = '(4,)'的SQL语句,数据库里的gameId是整数类型,自然匹配不到任何数据,所以返回空的结果集。
修正方案
方案1:正确提取ID并优化查询
先把gameIds里的整数ID提取出来,再用参数化查询(避免SQL注入,同时保证类型匹配)获取详情:
gameDay = event['gameDay'] gameMonth = event['gameMonth'] gameYear = event['gameYear'] secondGameDay = event['secondGameDay'] secondGameMonth = event['secondGameMonth'] secondGameYear = event['secondGameYear'] # 注意:你的formatter格式有问题,%e后面多了个%,应该是'%Y-%m-%d' formatter = '%Y-%m-%d' gameDetails = {} # 先查询所有符合条件的gameId search_sql = """ SELECT gameId FROM Games WHERE CAST(CONCAT_WS('-', gameYear, gameMonth, gameDay) AS DATE) BETWEEN DATE_FORMAT('2023-5-01', %s) AND DATE_FORMAT('2023-12-01', %s) """ # 用参数化查询替代f-string,更安全 cur.execute(search_sql, (formatter, formatter)) gameIds = cur.fetchall() # 提取每个元组里的第一个元素,得到纯整数ID列表 game_id_list = [row[0] for row in gameIds] # 遍历ID查询详情 for game_id in game_id_list: # 同样用参数化查询,把整数ID作为参数传入 list_sql = "SELECT * FROM Games WHERE gameId = %s" cur.execute(list_sql, (game_id,)) rows = cur.fetchall() # 可选:把查询结果转成字典(更易读,方便返回JSON) columns = [col[0] for col in cur.description] row_dict = dict(zip(columns, rows[0])) if rows else None # 用整数ID作为键存入结果字典 gameDetails[game_id] = row_dict return gameDetails
方案2:一次查询搞定(更高效)
其实你完全不需要先查ID再循环查询详情,直接一次查询出所有符合日期条件的游戏数据,再用gameId作为键构建字典,减少数据库交互次数:
gameDetails = {} # 直接查询符合日期范围的所有游戏详情 search_sql = """ SELECT * FROM Games WHERE CAST(CONCAT_WS('-', gameYear, gameMonth, gameDay) AS DATE) BETWEEN '2023-05-01' AND '2023-12-01' """ cur.execute(search_sql) # 获取字段名,用于把行转成字典 columns = [col[0] for col in cur.description] # 遍历结果构建字典 for row in cur.fetchall(): row_dict = dict(zip(columns, row)) game_id = row_dict['gameId'] gameDetails[game_id] = row_dict return gameDetails
额外提醒
- 避免用f-string拼接SQL语句,容易引发SQL注入风险,尤其是当
event里的参数来自用户输入时,一定要用参数化查询(cur.execute(sql, params)的形式)。 - 你原来的
formatter写了'%Y-%m-%e%',多了一个百分号,应该改成'%Y-%m-%d'或者'%Y-%m-%e'(%e是不带前导零的日期,%d是带前导零的)。
备注:内容来源于stack exchange,提问作者True_False_AX10M
相关产品推荐
相关产品推荐

