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

Flask-SQLAlchemy查询中如何修改日期格式适配JavaScript处理

报错根因

你调用strftime报错是因为函数和数据库不匹配:strftime是SQLite的内置日期函数,MySQL没有这个函数,自然会抛出函数不存在的错误。MySQL做日期格式化要用原生的DATE_FORMAT函数,SQLAlchemy里可以直接通过func.DATE_FORMAT调用。

推荐实现方案

方案1:查询阶段直接返回JS友好的年月格式(最稳妥)

直接在查询时把月份格式化为YYYY-MM形式的字符串,这是前后端交互时最适合处理的月份格式,不会出现排序错误、跨年数据混淆的问题,JS端拿到后既可以直接当X轴标签、分组键,也可以很方便地转成Date对象。
修改后的查询代码如下:

month = db.session.query(
    Certificates.msm,
    Certificates.certificate_type,
    func.count(Certificates.id),
    # 格式化为 年-月 字符串,比如3月返回"2024-03",给字段起别名方便后续取值
    func.DATE_FORMAT(Certificates.delivery_time, '%Y-%m').label('month')
).filter(
    Certificates.report_sent,
    Certificates.msm == msm
# 分组字段和查询的日期字段保持完全一致,避免SQL模式报错
).group_by(
    Certificates.certificate_type,
    Certificates.msm,
    func.DATE_FORMAT(Certificates.delivery_time, '%Y-%m')
).all()

查询返回的结果格式如下,直接序列化后传给前端即可:

[('bob', 'base-certificate', 60, '2024-03'), ('bob', 'case-certificate', 1, '2024-03'), ('bob', 'standard-certificate', 7, '2024-03')]

JS端处理示例:

// 直接作为标签使用无格式问题
const xAxisLabel = item.month // "2024-03"
// 转标准日期对象,无时区偏差
const dateObj = new Date(`${item.month}-01`)

如果你只需要两位的月份字符串,不需要年份,把DATE_FORMAT的格式参数改成'%m'即可,3月会返回'03'。

方案2:后端序列化阶段做格式转换

如果你不想修改原有查询逻辑,也可以在查询完成后、返回JSON前统一做格式处理:

formatted_data = []
for msm, cert_type, count, month_num in month:
    formatted_data.append({
        "msm": msm,
        "certificate_type": cert_type,
        "count": count,
        # 数字补零转成两位字符串,跨年场景建议额外拼接年份
        "month": f"{month_num:02d}"
    })

注意:纯月份数字/两位月份字符串存在跨年数据混淆的问题,如果你的业务数据可能跨年度,优先选方案1直接返回年+月的组合格式。

不推荐的做法

不要把纯整数月份直接传给前端再做格式处理:

  • 纯数字做图表X轴时会出现排序错误,10、11、12月会排在2月前面
  • 前端拼接日期时容易出现时区偏差、跨年逻辑遗漏的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:15:27