From d37403469492156193e94c6601f421cc5401d38a Mon Sep 17 00:00:00 2001 From: ZF sun <34314687@qq.com> Date: Wed, 3 Dec 2025 15:07:23 +0800 Subject: [PATCH] =?UTF-8?q?chore(docker):=20=E5=A2=9E=E5=8A=A0=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=E6=95=B0=E6=8D=AE=E5=BA=93=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- update_table_structure.py | 154 ++++++++++++++++++++++++++++++++++++-- upgrade.sql | 19 +++-- 2 files changed, 157 insertions(+), 16 deletions(-) diff --git a/update_table_structure.py b/update_table_structure.py index b0f11454b..ad38ac2f2 100644 --- a/update_table_structure.py +++ b/update_table_structure.py @@ -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__': diff --git a/upgrade.sql b/upgrade.sql index b78e0702a..c6346222b 100644 --- a/upgrade.sql +++ b/upgrade.sql @@ -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);