import pandas as pd import sqlalchemy from sqlalchemy import create_engine import configparser import os from urllib.parse import quote_plus def get_db_connection_string(config, section): """ 从配置文件中构建数据库连接字符串 :param config: 配置解析器对象 :param section: 配置节名(source_db或target_db) :return: 数据库连接字符串 """ db_type = 'mysql' # 假设使用MySQL数据库,可根据实际情况修改 driver = 'pymysql' # MySQL驱动 return f"{db_type}+{driver}://{config[section]['user']}:{quote_plus(config[section]['password'])}@" \ f"{config[section]['host']}:{config[section]['port']}/{config[section]['database']}" def transform_and_load_bm_unit(config_file_path): """ 从源数据库提取bm_unit数据,转换后加载到目标数据库 :param config_file_path: 配置文件路径 """ # 读取配置文件 if not os.path.exists(config_file_path): raise FileNotFoundError(f"配置文件不存在: {config_file_path}") config = configparser.ConfigParser() config.read(config_file_path) # 定义替换映射 type_id_mapping = { 1: 36, # 项目部 → 36 2: 33, # 施工队 → 33 3: 32, # 分包商 → 32 4: 1685, # 后勤科室 → 1685 5: 1704, # 外单位 → 1704 6: 1706 # 修试部门 → 1706 } dept_id_mapping = { 1: 327, # 送电一分公司 → 327 2: 102, # 送电二分公司 → 102 3: 309, # 宏源变电工程处 → 309 5: 338, # 土建分公司 → 338 8: 309, # 宏源送电工程处 → 309 9: 100, # 变电分公司 → 100 10: 101, # 机具(物流)分公司 → 101 11: 345, # 外部往来单位 → 345 12: 344, # 机械化分公司 → 344 13: 346, # 运检分公司 → 346 15: 340, # 安徽顺全电力工程有限公司 → 340 16: 337, # 检修试验分公司 → 337 17: 339, # 安徽顺安电网建设有限公司 → 339 18: 342, # 公司机关 → 342 21: 341 # 班组管理中心 → 341 } try: # 获取数据库连接字符串 source_conn_str = get_db_connection_string(config, 'source_db') target_conn_str = get_db_connection_string(config, 'target_db') # 创建数据库引擎 source_engine = create_engine(source_conn_str) target_engine = create_engine(target_conn_str) # 从源数据库读取数据 print("正在从源数据库读取bm_unit表数据...") source_query = """ SELECT ID, NAME, TYPE_ID, COMPANY_ID, time, COMPANY, IS_ACTIVE FROM bm_unit WHERE COMPANY = 1 AND IS_ACTIVE = 1 \ """ source_df = pd.read_sql(source_query, source_engine) if source_df.empty: print("没有符合条件的数据需要转换") return print(f"读取到{len(source_df)}条待转换数据") # 数据转换 print("正在进行数据转换...") target_df = pd.DataFrame() target_df['unit_id'] = source_df['ID'] target_df['unit_name'] = source_df['NAME'] target_df['type_id'] = source_df['TYPE_ID'].map(type_id_mapping) target_df['dept_id'] = source_df['COMPANY_ID'].map(dept_id_mapping) target_df['create_time'] = source_df['time'] # 检查是否有未映射的值 if target_df['type_id'].isna().any(): unmapped_types = source_df[target_df['type_id'].isna()]['TYPE_ID'].unique() print(f"警告: 发现未映射的TYPE_ID值: {unmapped_types}") if target_df['dept_id'].isna().any(): unmapped_depts = source_df[target_df['dept_id'].isna()]['COMPANY_ID'].unique() print(f"警告: 发现未映射的COMPANY_ID值: {unmapped_depts}") # 写入目标数据库 print("正在将数据写入目标数据库...") target_df.to_sql( 'bm_unit', target_engine, if_exists='append', index=False, dtype={ 'unit_id': sqlalchemy.types.INTEGER(), 'unit_name': sqlalchemy.types.VARCHAR(length=255), 'type_id': sqlalchemy.types.INTEGER(), 'dept_id': sqlalchemy.types.INTEGER(), 'create_time': sqlalchemy.types.DateTime() } ) print(f"成功写入{len(target_df)}条数据到目标数据库") except Exception as e: print(f"处理过程中发生错误: {str(e)}") raise finally: # 关闭数据库连接 if 'source_engine' in locals(): source_engine.dispose() if 'target_engine' in locals(): target_engine.dispose() # 使用示例 if __name__ == "__main__": # 配置文件路径 config_file = "config.ini" # 假设配置文件在当前目录下 try: # 执行转换 transform_and_load_bm_unit(config_file) except Exception as e: print(f"程序执行失败: {str(e)}")