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

MySQL查询返回None问题排查:获取近7天数据失败

问题描述

我正在编写一个从SQL数据库中获取近7天数据的函数,但遇到了问题。函数代码如下:

def get_last_7_days(mycursor):
    current_date = dt.now().date()
    date_minus_7 = dt.today() - td(days=7)
    dates = pd.date_range(date_minus_7.date(), current_date)
    for date in dates:
        row = mycursor.execute(f"SELECT * FROM work_times WHERE date = {date.date()}")
        print(row)

问题在于,即便列名正确且数据库中存在匹配日期的记录,execute语句仍返回None。

查询的表结构及数据如下:

+------------+------------+----------+--------------+------+
| date       | start_time | end_time | hours_worked | pay  |
+------------+------------+----------+--------------+------+
| 2023-08-09 | 07:00:00   | 14:30:00 |            7 |   81 |
| 2023-08-08 | 14:30:00   | 22:00:00 |            7 |   81 |
| 2023-08-07 | 07:00:00   | 14:30:00 |            7 |   81 |
| 2023-08-06 | 14:00:00   | 22:00:00 |            8 |   89 |
+------------+------------+----------+--------------+------+

我尝试了多种方法:将date转为字符串、给date.date()加引号、使用execute占位符(%s)、子查询日期范围、列名加反引号等,但均未解决。不过在终端执行SELECT * FROM work_times WHERE date = '2023-08-09';能正常返回结果。我打算先转成DataFrame用Pandas查询,但想先了解该语句失效的原因,恳请各位帮忙解答。

问题原因与解决方法

1. execute方法本身不返回查询结果

不管SQL查询是否命中数据,mycursor.execute()执行后默认返回None,你需要调用游标对应的方法来获取实际查询结果,比如:

  • mycursor.fetchone():获取单条记录
  • mycursor.fetchall():获取所有匹配记录
  • mycursor.fetchmany(n):获取指定数量的记录

你之前的代码里,row变量接收的是execute的返回值,自然是None,这和SQL语句是否正确无关。

2. SQL语句的语法问题(字符串拼接导致日期格式错误)

用f-string拼接{date.date()}时,生成的SQL语句是SELECT * FROM work_times WHERE date = 2023-08-09,这在SQL中会被解析为数学运算(2023减8减9),而非日期字符串,导致查询匹配失败。

正确的做法是使用参数化查询(占位符),既避免SQL注入风险,又能保证日期格式正确:

def get_last_7_days(mycursor):
    current_date = dt.now().date()
    date_minus_7 = dt.today() - td(days=7)
    dates = pd.date_range(date_minus_7.date(), current_date)
    for date in dates:
        mycursor.execute("SELECT * FROM work_times WHERE date = %s", (date.date(),))
        row = mycursor.fetchone()  # 或根据需求用fetchall()
        print(row)

3. 优化建议:一次查询替代循环遍历日期

没必要循环每个日期单独查询,直接用日期范围查询可减少数据库交互次数,效率更高:

def get_last_7_days(mycursor):
    current_date = dt.now().date()
    date_minus_7 = dt.today() - td(days=7)
    mycursor.execute("SELECT * FROM work_times WHERE date BETWEEN %s AND %s", (date_minus_7.date(), current_date))
    all_rows = mycursor.fetchall()
    for row in all_rows:
        print(row)

如果用Pandas处理,直接用pd.read_sql会更便捷:

import pandas as pd
def get_last_7_days_pandas(conn):
    current_date = dt.now().date()
    date_minus_7 = dt.today() - td(days=7)
    query = "SELECT * FROM work_times WHERE date BETWEEN %s AND %s"
    df = pd.read_sql(query, conn, params=(date_minus_7.date(), current_date))
    print(df)

内容的提问来源于stack exchange,提问作者Goon-Bug

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:42:34