chore(docker): 增加升级数据库脚本

This commit is contained in:
2025-12-03 15:07:23 +08:00
parent b0f399c814
commit d374034694
2 changed files with 157 additions and 16 deletions

View File

@@ -218,6 +218,120 @@ def update_table_structure(init_table, niushop_columns):
return new_create_sql
# 提取INSERT语句
def extract_insert_statements(sql_content):
"""从SQL文件中提取INSERT语句包括完整的列名和值"""
insert_statements = {}
# 匹配所有INSERT语句使用更可靠的方式处理
# 先分割SQL文件为多个语句
statements = sql_content.split(';')
for stmt in statements:
stmt = stmt.strip()
if not stmt:
continue
# 检查是否是INSERT语句
if stmt.upper().startswith('INSERT INTO'):
try:
# 提取表名
table_name_start = stmt.find('INSERT INTO') + len('INSERT INTO')
table_name_end = stmt.find('(')
table_name_part = stmt[table_name_start:table_name_end].strip()
# 去掉反引号
table_name = table_name_part.strip('`')
# 提取列名
columns_start = table_name_end + 1
columns_end = stmt.find(')', columns_start)
columns_str = stmt[columns_start:columns_end].strip()
# 提取VALUES部分
values_start = stmt.find('VALUES') + len('VALUES')
values_part = stmt[values_start:].strip()
# 处理VALUES部分提取所有括号对
values = []
bracket_count = 0
current_value = ''
in_quotes = False
quote_char = ''
for char in values_part:
if char in ('"', "'") and (not current_value or current_value[-1] != '\\'):
if not in_quotes:
in_quotes = True
quote_char = char
elif char == quote_char:
in_quotes = False
if char == '(' and not in_quotes:
bracket_count += 1
current_value = '('
elif char == ')' and not in_quotes:
bracket_count -= 1
current_value += ')'
if bracket_count == 0:
# 去掉括号
value_content = current_value[1:-1].strip()
if value_content:
values.append(value_content)
current_value = ''
elif bracket_count > 0:
current_value += char
if table_name not in insert_statements:
insert_statements[table_name] = {
'columns': columns_str,
'values': []
}
insert_statements[table_name]['values'].extend(values)
except Exception as e:
# 跳过格式不正确的INSERT语句
continue
return insert_statements
# 比较数据差异,生成数据升级语句
def generate_data_upgrade_statements(niushop_inserts, init_inserts, table_mapping):
"""生成数据升级语句"""
upgrade_statements = []
for niushop_table, niushop_insert_info in niushop_inserts.items():
# 检查init.sql中是否有对应的表
if niushop_table in table_mapping:
init_table = table_mapping[niushop_table]
# 获取niushop_database.sql中的列名和值
columns_str = niushop_insert_info.get('columns', '')
niushop_values = niushop_insert_info.get('values', [])
# 获取init.sql中对应表的数据
init_insert_info = init_inserts.get(init_table, {})
init_values = init_insert_info.get('values', [])
# 生成缺失数据的INSERT语句
for niushop_value in niushop_values:
# 过滤掉无效的VALUES如包含列名的VALUES
if 'store_name' in niushop_value and 'site_id' in niushop_value:
continue
# 过滤掉太短的值,可能是解析错误
if len(niushop_value) < 5:
continue
if niushop_value not in init_values:
# 构建完整的INSERT语句包含列名
if columns_str:
insert_stmt = f"INSERT INTO `{init_table}` ({columns_str}) VALUES ({niushop_value});"
else:
# 如果没有列名使用简化的INSERT语句
insert_stmt = f"INSERT INTO `{init_table}` VALUES ({niushop_value});"
upgrade_statements.append(insert_stmt)
return upgrade_statements
# 主函数
def main():
# 文件路径
@@ -240,9 +354,17 @@ def main():
init_tables = extract_init_table_structures(init_content)
print(f"从init.sql提取到 {len(init_tables)} 个表结构")
# 创建表名映射niushop_table -> init_table
table_mapping = {}
for init_table_name, init_table in init_tables.items():
original_table_name = init_table_name
if original_table_name.startswith('lucky_'):
original_table_name = original_table_name[6:] # 去掉lucky_前缀
table_mapping[original_table_name] = init_table_name
# 比较表结构差异,生成更新
print("正在比较表结构差异...")
upgrade_statements = []
structure_upgrade_statements = []
updated_init_content = init_content
# 遍历init.sql中的所有表
@@ -278,29 +400,49 @@ def main():
# 提取列名(带反引号)
col_name_in_def = col['definition'].split(' ')[0]
alter_stmt = f"ALTER TABLE `{init_table_name}` ADD COLUMN {col['definition']};"
upgrade_statements.append(alter_stmt)
structure_upgrade_statements.append(alter_stmt)
# 更新init.sql中的表结构
new_create_sql = update_table_structure(init_table, niushop_cols)
updated_init_content = updated_init_content.replace(init_table['full_sql'], new_create_sql)
# 提取INSERT语句生成数据升级
print("正在提取INSERT语句...")
niushop_inserts = extract_insert_statements(niushop_content)
init_inserts = extract_insert_statements(init_content)
print("正在生成数据升级语句...")
data_upgrade_statements = generate_data_upgrade_statements(niushop_inserts, init_inserts, table_mapping)
# 写入升级脚本
print("正在写入升级脚本...")
with open(upgrade_file, 'w', encoding='utf-8') as f:
f.write("-- 数据库升级脚本\n")
f.write("-- 生成时间: 自动生成\n")
f.write("-- 描述: 根据niushop_database.sql更新init.sql的表结构\n\n")
f.write("-- 描述: 根据niushop_database.sql更新init.sql的表结构和数据\n\n")
f.write("USE shop_mallnew;\n\n")
for stmt in upgrade_statements:
f.write(f"{stmt}\n")
# 写入表结构升级语句
if structure_upgrade_statements:
f.write("-- 表结构升级语句\n")
for stmt in structure_upgrade_statements:
f.write(f"{stmt}\n")
f.write("\n")
# 写入数据升级语句
if data_upgrade_statements:
f.write("-- 数据升级语句\n")
for stmt in data_upgrade_statements:
f.write(f"{stmt}\n")
# 更新init.sql文件
print("正在更新init.sql文件...")
with open(init_file, 'w', encoding='utf-8') as f:
f.write(updated_init_content)
print(f"升级脚本已生成,共 {len(upgrade_statements)} 条ALTER语句")
total_statements = len(structure_upgrade_statements) + len(data_upgrade_statements)
print(f"升级脚本已生成,共 {total_statements} 条语句")
print(f"其中表结构升级语句 {len(structure_upgrade_statements)} 条,数据升级语句 {len(data_upgrade_statements)}")
print(f"升级脚本路径: {upgrade_file}")
if __name__ == '__main__':

View File

@@ -1,6 +1,6 @@
-- 数据库升级脚本
-- 生成时间: 自动生成
-- 描述: 根据niushop_database.sql更新init.sql的表结构
-- 描述: 根据niushop_database.sql更新init.sql的表结构和数据
USE shop_mallnew;
@@ -55,12 +55,11 @@ ALTER TABLE `lucky_user` ADD COLUMN `create_uid` int NOT NULL DEFAULT '0' COMMEN
-- 数据升级语句
USE shop_mallnew;
INSERT INTO `lucky_cashier_auth_group` VALUES ('门店管理', '', 'admin', 1, '');
INSERT INTO `lucky_cashier_auth_group` VALUES ('收银', 'cashier,billing,buycard,recharge', '', 1, '');
INSERT INTO `lucky_cashier_auth_group` VALUES ('核销员', 'verify_manage,verify_index,verify_record,verify_code_info,verify', '', 1, '');
INSERT INTO `lucky_store` VALUES ('默认总店',1,1,'store', 1);
INSERT INTO `lucky_cron` VALUES (2, 2, 0, '统计更新(按时)', 'CronStatShopHour', 1700447491, 0, 0);
INSERT INTO `lucky_cron` VALUES (2, 2, 0, '店统计更新(按)', 'CronStatStoreHour', 1700447491, 0, 0);
INSERT INTO `lucky_cron` VALUES (2, 2, 0, '统计更新(按日)', 'CronStatShop', 1700447491, 0, 0);
INSERT INTO `lucky_cron` VALUES (2, 2, 0, '门店统计更新(按日)', 'CronStatStore', 1700447491, 0, 0);
INSERT INTO `lucky_cashier_auth_group` (`group_name`, `menu_array`, `keyword`, `site_id`, `desc`) VALUES ('门店管理员', '', 'admin', 1, '');
INSERT INTO `lucky_cashier_auth_group` (`group_name`, `menu_array`, `keyword`, `site_id`, `desc`) VALUES ('收银', 'cashier,billing,buycard,recharge', '', 1, '');
INSERT INTO `lucky_cashier_auth_group` (`group_name`, `menu_array`, `keyword`, `site_id`, `desc`) VALUES ('核销', 'verify_manage,verify_index,verify_record,verify_code_info,verify', '', 1, '');
INSERT INTO `lucky_store` (`store_name`,`site_id`,`status`,`stock_type`,`is_default`) VALUES ('默认总店',1,1,'store', 1);
INSERT INTO `lucky_cron` (`type`, `period`, `period_type`, `name`, `event`, `execute_time`, `relate_id`, `create_time`) VALUES (2, 2, 0, '店铺统计更新(按时)', 'CronStatShopHour', 1700447491, 0, 0);
INSERT INTO `lucky_cron` (`type`, `period`, `period_type`, `name`, `event`, `execute_time`, `relate_id`, `create_time`) VALUES (2, 2, 0, '店统计更新(按时)', 'CronStatStoreHour', 1700447491, 0, 0);
INSERT INTO `lucky_cron` (`type`, `period`, `period_type`, `name`, `event`, `execute_time`, `relate_id`, `create_time`) VALUES (2, 2, 0, '统计更新(按)', 'CronStatShop', 1700447491, 0, 0);
INSERT INTO `lucky_cron` (`type`, `period`, `period_type`, `name`, `event`, `execute_time`, `relate_id`, `create_time`) VALUES (2, 2, 0, '店统计更新(按日)', 'CronStatStore', 1700447491, 0, 0);