Files
ylt_diy/lib/db_init.py
2026-07-20 16:42:56 +08:00

189 lines
8.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
数据库初始化
"""
from lib.db import execute_update, execute_query
from lib.logger import log_info, log_error, log_warning
def _column_exists(table_name, column_name):
"""检查字段是否存在(通过 information_schema 查询)"""
try:
result = execute_query("""
SELECT COUNT(*) as cnt
FROM information_schema.columns
WHERE table_schema = DATABASE()
AND table_name = %s
AND column_name = %s
""", (table_name, column_name))
return result and result[0]['cnt'] > 0
except Exception:
return False
def _add_column_if_not_exists(table_name, column_def_sql, column_name):
"""安全地添加字段:先检查是否存在,不存在再添加"""
if _column_exists(table_name, column_name):
log_info(f"[数据库] 字段 {table_name}.{column_name} 已存在,跳过", 'db_init')
return True
try:
execute_update(f"ALTER TABLE {table_name} ADD COLUMN {column_def_sql}")
log_info(f"[数据库] 新增字段 {table_name}.{column_name} 成功", 'db_init')
return True
except Exception as e:
log_warning(f"[数据库] 新增字段 {table_name}.{column_name} 失败: {e}", 'db_init')
return False
def _set_table_comment(table_name, comment):
"""设置表备注Doris暂不支持通过SQL修改表注释预留函数"""
pass
def init_database_tables():
"""初始化所有数据库表(应用启动时自动调用)"""
try:
# 创建配置表
create_config_table = """
CREATE TABLE IF NOT EXISTS 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 '求和字段列表',
time_periods VARCHAR(1000) NULL COMMENT '分时段电量配置',
merge_telecom TINYINT NULL COMMENT '是否合并特来电数据',
telecom_vehicle_no VARCHAR(500) NULL COMMENT '特来电车量自编号',
field_custom_names VARCHAR(2000) NULL COMMENT '字段自定义报表名头',
show_monthly_total TINYINT NULL COMMENT '是否显示当月充电量总计',
custom_service_fee_price DECIMAL(10,4) NULL COMMENT '自定义服务费单价(元/kWh)',
custom_service_fee_name VARCHAR(100) 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")
"""
execute_update(create_config_table)
_set_table_comment('t_daily_report_config', '日报配置表')
log_info("[数据库] t_daily_report_config 表已就绪", 'db_init')
# 创建历史表
create_history_table = """
CREATE TABLE IF NOT EXISTS 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',
config_name VARCHAR(200) NULL COMMENT '配置名称',
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")
"""
execute_update(create_history_table)
_set_table_comment('t_daily_report_history', '日报生成历史记录表')
log_info("[数据库] t_daily_report_history 表已就绪", 'db_init')
# 为已存在的表添加 config_name 字段(如果不存在)
_add_column_if_not_exists(
't_daily_report_history',
"config_name VARCHAR(200) NULL COMMENT '配置名称'",
'config_name'
)
# 创建求和数据表
create_sum_data_table = """
CREATE TABLE IF NOT EXISTS t_daily_report_sum_data (
id BIGINT NOT NULL COMMENT '主键 ID',
report_date VARCHAR(20) NULL COMMENT '报表日期',
config_id BIGINT NULL COMMENT '配置 ID',
config_name VARCHAR(200) NULL COMMENT '配置名称',
split_type VARCHAR(20) NULL COMMENT '拆分方式',
split_value VARCHAR(100) NULL COMMENT '拆分值',
split_name VARCHAR(200) NULL COMMENT '拆分显示名称',
sum_field_key VARCHAR(100) NULL COMMENT '求和字段键名',
sum_field_name VARCHAR(100) NULL COMMENT '求和字段中文名称',
sum_value DECIMAL(18,3) NULL COMMENT '求和值',
total_orders INT NULL COMMENT '订单数',
sort_order INT NULL COMMENT '配置排序号',
data_source VARCHAR(20) NULL COMMENT '数据来源 auto=自动采集 manual=手动编辑',
remark VARCHAR(500) 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")
"""
execute_update(create_sum_data_table)
_set_table_comment('t_daily_report_sum_data', '日报求和数据采集表')
log_info("[数据库] t_daily_report_sum_data 表已就绪", 'db_init')
# 给配置表增加 show_monthly_total 字段
_add_column_if_not_exists(
't_daily_report_config',
"show_monthly_total TINYINT NULL COMMENT '是否显示当月充电量总计'",
'show_monthly_total'
)
# 给求和数据表增加 sort_order 字段
_add_column_if_not_exists(
't_daily_report_sum_data',
"sort_order INT NULL COMMENT '配置排序号'",
'sort_order'
)
# 给配置表增加 custom_service_fee_price 字段(自定义服务费单价)
_add_column_if_not_exists(
't_daily_report_config',
"custom_service_fee_price DECIMAL(10,4) NULL COMMENT '自定义服务费单价(元/kWh)'",
'custom_service_fee_price'
)
# 给配置表增加 custom_service_fee_name 字段(自定义服务费表头名称)
_add_column_if_not_exists(
't_daily_report_config',
"custom_service_fee_name VARCHAR(100) NULL COMMENT '自定义服务费报表表头名称'",
'custom_service_fee_name'
)
# 数据迁移:给 sort_order 为 NULL 的配置记录按 id 顺序赋值
try:
null_count = execute_query(
"SELECT COUNT(*) as cnt FROM t_daily_report_config WHERE sort_order IS NULL"
)
if null_count and null_count[0]['cnt'] > 0:
log_info(f"[数据库] 检测到 {null_count[0]['cnt']} 条配置 sort_order 为空,开始初始化排序...", 'db_init')
all_configs = execute_query(
"SELECT id FROM t_daily_report_config ORDER BY id ASC"
)
for idx, cfg in enumerate(all_configs):
execute_update(
"UPDATE t_daily_report_config SET sort_order = %s WHERE id = %s",
(idx + 1, cfg['id'])
)
log_info("[数据库] 配置 sort_order 初始化完成", 'db_init')
except Exception as e:
log_warning(f"[数据库] 初始化 sort_order 时出错: {e}", 'db_init')
log_info("[数据库] 初始化完成", 'db_init')
return True
except Exception as e:
log_error(f"[数据库] 初始化失败: {e}", 'db_init', exc_info=True)
return False