目录

一、适合场景

二、开发过程说明

三、功能使用流程

四、代码

1、安装python依赖库

2、完整代码段


一、适合场景

无废话,CSV中有少量不合规数据需要手工处理可利用此方法,适合有点经验的程序员,可以不熟Python,思路还是要有一点

二、开发过程说明

本人不熟Python,chatGPT由于网络问题总是不太好用,利用了文心一言,辅助实现了相关代码

csv文件导入MySQL数据库乱码怎么解决 csv文件如何导入mysql_mysql

三、功能使用流程

看“main()”函数,

1、修改Mysql数据链接

2、定义好导入的文件和表对,文件都要在变量path目录下,格局需要修改,也可path放空,在map对里面直接写完整的文件名

3、导入

导入的过程:错误的行通过“异常”抓去出来,保存到-error.csv结尾的文件中,以便后续继续处理,原来导入的文件只留下正确的可导入的数据

四、代码

1、安装python依赖库

# 先要运行这个安装依赖的包
pip install pandas sqlalchemy pymysql cryptography

2、完整代码段

# 调整修复 2024-03-29 17:19

# 先要运行这个安装依赖的包
# pip install pandas sqlalchemy pymysql cryptography

import pandas as pd
import re
from sqlalchemy import create_engine  
import csv
import os

def delete_line_from_file_and_backup(file_path, line_number, output_file):  
    with open(file_path, 'r') as file:  
        lines = file.readlines()  
      
    if not os.path.isfile(output_file):
        isNewFile = True
    else:
        isNewFile = False
    # 先备份记录
    with open(output_file, mode='a', newline='') as file:
        if isNewFile:
            file.writelines(lines[0])
            print('=========================')
            print(lines[0])
        file.seek(os.SEEK_END)
        file.writelines(lines[line_number])

    # 删除指定行数的行(注意Python的索引是从0开始的)  
    del lines[line_number]
      
    # 将修改后的内容写回文件,可以选择写入新文件或覆盖原文件  
    with open(file_path, 'w') as file:  
        file.writelines(lines) 


#取得导入出错的CSV文件的行号
def getErrorLineNo(s):
    
    # 使用正则表达式查找行号  
    line_number_match = re.search(r'in line (\d+)', s)  
    
    # 如果找到了匹配项,提取数字  
    if line_number_match:  
        line_number = int(line_number_match.group(1))  
        #print(line_number)  # 输出: 13092  
        return line_number
    else:  
        # 使用正则表达式查找行号  
        line_number_match = re.search(r'at row (\d+)', s)  
        
        # 如果找到了匹配项,提取数字  
        if line_number_match:  
            line_number = int(line_number_match.group(1))  
            #print(line_number)  # 输出: 13092  
            return line_number
        else:  
            #print("未找到行号")
            return 0
# 完成导入    
def doImport(engine, path, file_to_table_map):
    # 循环遍历字典,读取CSV文件并将数据导入到对应的MySQL表中  
    for csv_file, table_name in file_to_table_map.items():

        # 循环将所有的导入异常全部抓去出来,保存到外面的CSV文件中
        # 将剩余的导入到数据库中,有问题的CSV文件,需要手工处理后再导入
        while True:
            try:
                # 使用函数导入CSV文件  
                print('正在导入数据到表:', table_name, " <--- ", path + csv_file)
                df = pd.read_csv(path + csv_file, sep='\t')  
                df.to_sql(table_name, engine, if_exists='replace', index=False)
                print('导入完成:', table_name)
                break;
            except Exception as e:
                print('导入失败:', table_name, e)
                row_to_delete = getErrorLineNo(str(e))
                if row_to_delete >= 0:
                    srcFile = path + csv_file
                    bakFile = srcFile + '-error.csv'
                    print('备份&删除&回写:', table_name, path + bakFile)
                    delete_line_from_file_and_backup(srcFile, row_to_delete, bakFile)
                else:
                    break

def main():
    # 创建数据库连接引擎  
    engine = create_engine('mysql+pymysql://root:123456@localhost:3306/hjyb',)  

    # 格式:'文件名': '表名'
    file_to_table_map = {
        # 'tb_a.csv': 'tb_a',
        # 'tb_b.csv': 'tb_b',
        # 'tb_c.csv': 'tb_c',
        # 'tb_d.csv': 'tb_d'
    }

    # 测试数据目录
    path = '/Users/zhengjie/working/xx系统/测试数据/'
    doImport(engine, path, file_to_table_map)

if __name__ == '__main__':
    main()