B002-操作系统:设计及实现-进程总结

博客提及与操作系统相关内容,但仅表明见图,未给出具体信息。

这里写图片描述

见图!

这个错误是因为在使用 `executemany` 批量更新数据库时,参数格式不正确。以下是修正后的完整脚本和解决方案: --- ### **错误分析与修复** #### **问题原因** 1. `executemany` 要求参数必须是字典列表(当使用命名参数时)或元组列表(当使用位置参数时) 2. 当前代码混合使用了两种风格 #### **关键修复** 1. 统一使用元组列表格式 2. 改进数据库更新逻辑 --- ### **修正后的完整脚本** ```python import os import pandas as pd from sqlalchemy import create_engine import logging from datetime import datetime # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # 数据库配置 DB_CONFIG = { 'host': 'your_host', 'port': 3306, 'user': 'your_user', 'password': 'your_password', 'database': 'your_db', 'charset': 'latin1' } def get_script_directory(): """获取脚本所在目录""" try: return os.path.dirname(os.path.abspath(__file__)) except NameError: return os.getcwd() def count_xlsx_files(): """统计xlsx文件""" script_dir = get_script_directory() os.chdir(script_dir) logger.info(f"当前工作目录: {os.getcwd()}") logger.info(f"目录内容: {os.listdir('.')}") file_stats = {} for filename in os.listdir('.'): if filename.startswith('~$') or not filename.lower().endswith('.xlsx'): continue filepath = os.path.join(script_dir, filename) try: logger.info(f"正在处理文件: {filename}") with pd.ExcelFile(filepath, engine='openpyxl') as xls: for sheet_name in xls.sheet_names: df = pd.read_excel(xls, sheet_name=sheet_name) # 检查必要列是否存在 if not all(col in df.columns for col in ['sub_name', 'dist_id']): logger.warning(f"文件 {filename} 缺少必要列") continue for _, row in df.iterrows(): sub_name = str(row['sub_name']).strip() dist_id = str(row['dist_id']).strip() if sub_name and dist_id: key = (sub_name, dist_id) file_stats[key] = file_stats.get(key, 0) + 1 except Exception as e: logger.error(f"处理文件 {filename} 失败: {str(e)}") continue return file_stats def update_database(file_stats): """更新数据库(修正批量操作)""" try: engine = create_engine( f"mysql+pymysql://{DB_CONFIG['user']}:{DB_CONFIG['password']}" f"@{DB_CONFIG['host']}:{DB_CONFIG['port']}/{DB_CONFIG['database']}", connect_args={'charset': 'latin1'} ) current_date = datetime.now().strftime('%Y-%m-%d') updates = [] for (sub_name, dist_id), count in file_stats.items(): # 转换为Latin1兼容格式 safe_sub = sub_name.encode('gbk').decode('latin1', errors='ignore') safe_dist = dist_id.encode('gbk').decode('latin1', errors='ignore') # 使用元组格式(位置参数) updates.append((current_date, safe_sub, safe_dist, count)) with engine.begin() as conn: # 使用位置参数风格的批量操作 conn.execute( """INSERT INTO file_stats (collection_date, sub_name, dist_id, count) VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE count = VALUES(count)""", updates ) except Exception as e: logger.error(f"数据库操作失败: {str(e)}", exc_info=True) raise if __name__ == "__main__": try: logger.info("====== 开始执行统计 ======") stats = count_xlsx_files() if not stats: logger.warning("未找到有效数据,请检查:") logger.warning("1. Excel文件是否包含sub_name和dist_id列") logger.warning("2. 数据是否非空") else: logger.info(f"共统计到 {len(stats)} 条有效数据") update_database(stats) logger.info("数据库更新成功") except Exception as e: logger.error(f"程序运行异常: {str(e)}", exc_info=True) finally: logger.info("====== 执行结束 ======") ``` --- ### **关键改进点** 1. **数据库批量操作修正** ```python # 原错误代码(混合风格) # 修正为统一使用位置参数风格的元组列表 updates.append((current_date, safe_sub, safe_dist, count)) ``` 2. **增强健壮性** - 检查必要列是否存在: ```python if not all(col in df.columns for col in ['sub_name', 'dist_id']): logger.warning(f"文件 {filename} 缺少必要列") ``` 3. **改进错误日志** - 添加 `exc_info=True` 显示完整堆栈: ```python logger.error(f"数据库操作失败: {str(e)}", exc_info=True) ``` 4. **编码处理优化** - 更安全的GBK→Latin1转换: ```python .decode('latin1', errors='ignore') ``` --- ### **验证测试** 1. **测试数据准备** ```python # 测试用Excel文件应包含: # | sub_name | dist_id | # |----------|---------| # | 北京 | A001 | # | 上海 | B002 | ``` 2. **预期输出** ``` 2025-08-07 15:30:00,014 - INFO - ====== 开始执行统计 ====== 2025-08-07 15:30:00,020 - INFO - 正在处理文件: test.xlsx 2025-08-07 15:30:01,290 - INFO - 共统计到 2 条有效数据 2025-08-07 15:30:01,845 - INFO - 数据库更新成功 2025-08-07 15:30:01,846 - INFO - ====== 执行结束 ====== ``` 3. **数据库验证** ```sql SELECT collection_date, CONVERT(CONVERT(sub_name USING latin1) USING gbk) AS sub_name, CONVERT(CONVERT(dist_id USING latin1) USING gbk) AS dist_id, count FROM file_stats; ``` --- ### **常见问题处理** **Q1: 仍然出现编码错误怎么办?** - 尝试修改编码处理方式: ```python # 替代方案:UTF-8 → Latin1 safe_sub = sub_name.encode('utf-8').decode('latin1', errors='ignore') ``` **Q2: 如何提高大文件处理速度?** - 使用分块读取: ```python for chunk in pd.read_excel(xls, sheet_name=sheet_name, chunksize=1000): # 处理每个chunk ``` **Q3: 需要记录处理过的文件怎么办?** - 添加状态记录: ```python processed_files = set() if filename in processed_files: continue # 处理完成后 processed_files.add(filename) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值