Files
ylt_diy/fix_database.py
user9994793890 487a26e704 fix: 创建数据库表结构修复工具,解决下载按钮不显示的问题
问题:日报生成成功后,历史记录中显示"可下载为空",没有下载按钮。

原因:数据库表结构可能缺少 file_path 字段,或者表结构不完整。

解决方案:

1. 新增 fixDatabase.py 修复脚本:
   - 自动检查表结构是否完整
   - 检查是否缺少 file_path 等必要字段
   - 询问用户是否删除旧表重建
   - 重建 t_daily_report_history 和 t_daily_report_config 表
   - 显示最近的历史记录状态

2. 新增 修复下载问题.md 文档:
   - 详细的问题分析
   - 4种解决方案
   - 常见问题解答
   - 验证修复的方法

使用步骤:
1. 停止当前服务(Ctrl+C)
2. 运行 python fixDatabase.py
3. 输入 y 确认删除旧表重建
4. 重启服务 python app.py
5. 重新创建配置
6. 生成日报
7. 历史记录中应该能看到下载按钮

注意:修复会删除所有配置和历史记录,需要重新创建配置。

Coze-Commit-Type: user
Coze-User-ID: 3722323274763196
Coze-Conversation-ID: 9894087
2026-07-09 13:08:39 +08:00

209 lines
7.5 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
修复数据库表结构脚本
用于检查和修复 t_daily_report_history 表的 file_path 字段
"""
import pymysql
import sys
# 数据库配置
DB_CONFIG = {
'host': 'haoslm2.xicp.net',
'port': 10216,
'user': 'root',
'password': 'DsideaL147258369',
'database': 'yltcharge',
'charset': 'utf8mb4'
}
def check_table_structure():
"""检查表结构"""
try:
connection = pymysql.connect(**DB_CONFIG)
cursor = connection.cursor()
# 检查历史表是否存在
cursor.execute("SHOW TABLES LIKE 't_daily_report_history'")
result = cursor.fetchone()
if not result:
print("❌ t_daily_report_history 表不存在")
print("请先访问 http://localhost:5000/api/init-tables 初始化数据库")
return False
print("✓ t_daily_report_history 表存在")
# 检查表结构
cursor.execute("DESCRIBE t_daily_report_history")
columns = cursor.fetchall()
column_names = [col[0] for col in columns]
print(f"\n表结构包含 {len(columns)} 个字段:")
for col in columns:
print(f" - {col[0]}: {col[1]}")
# 检查是否有 file_path 字段
if 'file_path' not in column_names:
print("\n❌ 缺少 file_path 字段")
return False
print("\n✓ file_path 字段存在")
# 检查是否有其他必要字段
required_fields = ['id', 'report_date', 'start_time', 'end_time', 'split_type',
'split_value', 'split_name', 'config_id', 'total_orders',
'total_amount', 'sum_results', 'file_path', 'status', 'create_time']
missing_fields = [f for f in required_fields if f not in column_names]
if missing_fields:
print(f"\n❌ 缺少以下字段: {', '.join(missing_fields)}")
return False
print("✓ 所有必要字段都存在")
# 检查数据
cursor.execute("SELECT COUNT(*) FROM t_daily_report_history")
count = cursor.fetchone()[0]
print(f"\n历史记录数量: {count}")
if count > 0:
# 检查最近的记录
cursor.execute("""
SELECT id, status, file_path, report_date, split_name
FROM t_daily_report_history
ORDER BY create_time DESC
LIMIT 5
""")
records = cursor.fetchall()
print("\n最近5条记录:")
for record in records:
id, status, file_path, report_date, split_name = record
status_text = '成功' if status == 1 else '失败'
file_status = '有文件' if file_path else '无文件'
print(f" ID: {id}, 状态: {status_text}, {file_status}, 日期: {report_date}, 名称: {split_name}")
if status == 1 and not file_path:
print(f" ⚠️ 警告: 状态为成功但file_path为空!")
cursor.close()
connection.close()
return True
except Exception as e:
print(f"❌ 检查失败: {e}")
return False
def fix_table():
"""修复表结构(删除旧表重建)"""
try:
print("\n" + "="*50)
print("开始修复表结构...")
print("="*50)
connection = pymysql.connect(**DB_CONFIG)
cursor = connection.cursor()
# 删除旧表
print("\n1. 删除旧表...")
cursor.execute("DROP TABLE IF EXISTS t_daily_report_history")
print(" ✓ 已删除 t_daily_report_history")
cursor.execute("DROP TABLE IF EXISTS t_daily_report_config")
print(" ✓ 已删除 t_daily_report_config")
# 重建历史表
print("\n2. 重建历史表...")
create_history_table = """
CREATE TABLE t_daily_report_history (
id BIGINT NOT NULL COMMENT '历史ID',
report_date VARCHAR(20) NULL COMMENT '报表日期',
start_time VARCHAR(50) NULL COMMENT '开始时间',
end_time VARCHAR(50) NULL COMMENT '结束时间',
split_type VARCHAR(20) NULL COMMENT '拆分方式',
split_value VARCHAR(100) NULL COMMENT '拆分值',
split_name VARCHAR(200) NULL COMMENT '拆分显示名称',
config_id BIGINT NULL COMMENT '配置ID',
total_orders INT NULL COMMENT '订单总数',
total_amount DECIMAL(10,2) NULL COMMENT '总金额',
sum_results VARCHAR(2000) NULL COMMENT '求和结果',
file_path VARCHAR(500) NULL COMMENT '文件路径',
status TINYINT NULL COMMENT '状态',
create_time DATETIME NULL COMMENT '创建时间'
)
UNIQUE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES("replication_num" = "1")
"""
cursor.execute(create_history_table)
print(" ✓ 已创建 t_daily_report_history")
# 重建配置表
print("\n3. 重建配置表...")
create_config_table = """
CREATE TABLE t_daily_report_config (
id BIGINT NOT NULL COMMENT '配置ID',
config_name VARCHAR(100) NOT NULL COMMENT '配置名称',
split_type VARCHAR(20) NOT NULL COMMENT '拆分方式',
split_value VARCHAR(100) NOT NULL COMMENT '拆分值',
split_name VARCHAR(200) NULL COMMENT '拆分显示名称',
selected_fields VARCHAR(3000) NOT NULL COMMENT '选择的字段列表',
sum_fields VARCHAR(3000) NULL COMMENT '求和字段列表',
is_active TINYINT NULL COMMENT '是否启用',
sort_order INT NULL COMMENT '排序顺序',
create_time DATETIME NULL COMMENT '创建时间',
update_time DATETIME NULL COMMENT '更新时间'
)
UNIQUE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES("replication_num" = "1")
"""
cursor.execute(create_config_table)
print(" ✓ 已创建 t_daily_report_config")
connection.commit()
cursor.close()
connection.close()
print("\n" + "="*50)
print("✓ 表结构修复完成!")
print("="*50)
print("\n请重新创建配置并生成日报")
return True
except Exception as e:
print(f"\n❌ 修复失败: {e}")
return False
def main():
print("="*50)
print("数据库表结构检查和修复工具")
print("="*50)
# 检查表结构
print("\n【步骤1】检查表结构...")
if not check_table_structure():
# 询问是否修复
print("\n" + "="*50)
choice = input("是否删除旧表并重建?(y/n): ")
if choice.lower() == 'y':
fix_table()
else:
print("\n取消修复")
else:
print("\n" + "="*50)
print("✓ 表结构正常")
print("="*50)
print("\n如果仍然无法下载,请:")
print("1. 重启服务: python app.py")
print("2. 清除浏览器缓存: Ctrl+F5")
print("3. 重新生成日报")
print("\n按回车键退出...")
input()
if __name__ == '__main__':
main()