Flask+MySQL每日数据同步问题:JSON数组合并与目标表为空
问题分析与解决方案
一、jsondatadaily表为空的原因及修复
你当前代码存在几个直接导致数据插入失败的问题:
- 表名不匹配:实际表是
jsondata和jsondatadaily,但代码里写的是jsontable和jsontabledaily,完全对应不上,自然查不到数据进行插入。 - 日期格式冲突:示例数据中
date字段是dd.mm.yyyy格式(如28.09.2022),但代码生成的是%Y-%m-%d格式(如2022-09-28),用LIKE根本匹配不到对应数据。 - 未提交事务:Flask操作MySQL默认不会自动提交事务,执行
INSERT后必须调用commit(),否则操作不会持久化到数据库。 - SELECT逻辑错误:要按
ip、code分组,但直接选取原表的id会引发分组冲突(同一组有多个不同id),且jsondatadaily的id应设为自增主键,无需从原表获取。
二、合并同组JSON数组的解决方案
MySQL提供JSON_ARRAYAGG()函数,可直接将分组后的多个JSON数组合并为一个包含所有子数组的JSON数组;如果需要逗号分隔的字符串格式,可改用GROUP_CONCAT()。
修正后的完整代码
@app.route('/getnewalldaily') def getnew_alldaily(): now = datetime.datetime.now() # 生成与原表匹配的日期格式(dd.mm.yyyy) created_at = now.strftime('%d.%m.%Y') cursor = mysql.connection.cursor() # 修正SQL:表名+分组聚合+日期匹配+移除无效id insert_sql = """ INSERT INTO jsondatadaily(code, ip, date, data) SELECT code, ip, date, JSON_ARRAYAGG(data) AS merged_data -- 合并JSON数组为一个大JSON数组 FROM jsondata WHERE date = %s -- 直接匹配日期(适用于date为字符串类型的情况) GROUP BY ip, code, date """ cursor.execute(insert_sql, [created_at]) # 必须提交事务,数据才会写入数据库 mysql.connection.commit() cursor.execute('SELECT * FROM jsondatadaily') veriler = list(cursor.fetchall()) cursor.close() return render_template('/getnewalldaily.html', datas=veriler)
可选:如果需要逗号分隔的字符串格式
把JSON_ARRAYAGG(data)替换为GROUP_CONCAT(data SEPARATOR ','),即可得到[1,2],[3,4],[5,6]这种格式的结果。
三、额外优化建议
- 给
jsondatadaily设置自增主键id,避免插入时的主键冲突:
ALTER TABLE jsondatadaily MODIFY COLUMN id INT AUTO_INCREMENT PRIMARY KEY;
- 如果原表
date字段是DATE类型而非字符串,建议用MySQL的日期函数匹配,准确性更高:
# 生成标准DATE格式字符串(%Y-%m-%d) created_at = now.strftime('%Y-%m-%d') # SQL中用DATE()函数转换原表日期进行匹配 insert_sql = """ INSERT INTO jsondatadaily(code, ip, date, data) SELECT code, ip, DATE(date), JSON_ARRAYAGG(data) AS merged_data FROM jsondata WHERE DATE(date) = %s GROUP BY ip, code, DATE(date) """
内容的提问来源于stack exchange,提问作者whisber
相关产品推荐
相关产品推荐

