分享一个数据库批量修改的python脚本

本方法适用于批量修改Oracle数据库,还有就是不太会写sql的同学。喜欢点赞,不喜勿喷哦!

注:若要修改其他数据库的需安装对应的python组件

准备环境:python、Oracle数据库

下面是完整的代码:

import cx_Oracle
import pandas as pd
from datetime import datetime
import os
import traceback

# 配置信息(根据实际情况修改)
config = {
    "excel_path": "D:/testpython/info.xlsx",    # Excel文件路径
    "sheet_name": "Sheet1",              # 工作表名称
    "condition_col": "字段1",               # 条件列名(需要与数据库字段对应)
    "update_cols": ["字段2"],  # 需要更新的列名列表(需要与数据库字段对应)
    "oracle": {
        "user": "user",
        "password": "password",
        "dsn": "localhost:1521/orcl"
    },
    "log_file": "update_log.log"         # 日志文件路径
}

class ConditionAwareUpdater:
    def __init__(self):
        self.log_buffer = []
        self.start_time = datetime.now()

    def log(self, message, level="INFO"):
        """记录日志到内存缓冲区和控制台"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_entry = f"[{timestamp}] [{level}] {message}"
        self.log_buffer.append(log_entry)
        print(log_entry)

    def write_log_file(self):
        """保证日志写入文件的可靠性"""
        try:
            log_dir = os.path.dirname(config["log_file"])
            if log_dir and not os.path.exists(log_dir):
                os.makedirs(log_dir)
                
            with open(config["log_file"], "a", encoding="utf-8") as f:
                f.write("\n".join(self.log_buffer) + "\n")
            self.log_buffer = []
        except Exception as e:
            print(f"日志写入失败: {str(e)}")

    def connect_oracle(self):
        """建立数据库连接"""
        try:
            conn = cx_Oracle.connect(
                user=config["oracle"]["user"],
                password=config["oracle"]["password"],
                dsn=config["oracle"]["dsn"]
            )
            self.log(f"数据库连接成功(版本:{conn.version})")
            return conn
        except cx_Oracle.DatabaseError as e:
            self.log(f"数据库连接失败: {str(e)}", "ERROR")
            return None

    def read_excel_data(self):
        """读取并验证Excel数据"""
        try:
            if config["excel_path"].endswith('.csv'):
                df = pd.read_csv(config["excel_path"])
            else:
                df = pd.read_excel(
                    config["excel_path"], 
                    sheet_name=config["sheet_name"],
                    engine='openpyxl'
                )
            
            # 验证必要列
            required_cols = [config["condition_col"]] + config["update_cols"]
            if missing := list(set(required_cols) - set(df.columns)):
                raise ValueError(f"缺少必要列: {missing}")
            
            df = df.where(pd.notnull(df), None)
            self.log(f"读取到有效记录 {len(df)} 条")
            return df
        except Exception as e:
            self.log(f"Excel读取失败: {str(traceback.format_exc())}", "ERROR")
            return None

    def generate_update_sql(self, table_name="table_name"):#修改为自己的数据表名
        """生成参数化更新语句"""
        set_clause = ", ".join([f"{col} = :{col}" for col in config["update_cols"]])
        return f"""
        UPDATE {table_name}
        SET {set_clause}
        WHERE {config["condition_col"]} = :condition_val
        """

    def execute_safe_update(self, conn, df):
        """逐条执行更新并检查条件存在性"""
        cursor = conn.cursor()
        sql = self.generate_update_sql()
        total = len(df)
        success_count = 0
        
        try:
            for idx, row in df.iterrows():
                record_id = row[config["condition_col"]]
                params = {
                    "condition_val": record_id,
                    **{col: row[col] for col in config["update_cols"]}
                }
                
                try:
                    # 执行单条更新
                    cursor.execute(sql, params)
                    
                    if cursor.rowcount == 0:
                        self.log(f"更新失败 - 条件不存在: ID={record_id}", "WARNING")
                    else:
                        success_count += 1
                        self.log(f"更新成功: ID={record_id}")
                        
                except cx_Oracle.DatabaseError as e:
                    error_obj = e.args[0]
                    self.log(
                        f"数据库错误 - ID={record_id} "
                        f"[ORA-{error_obj.code}] {error_obj.message}",
                        "ERROR"
                    )
                    
            conn.commit()
        except Exception as e:
            conn.rollback()
            self.log(f"事务回滚: {str(traceback.format_exc())}", "CRITICAL")
        finally:
            cursor.close()
            
        return success_count, total

    def run(self):
        """主控制流程"""
        self.log("\n" + "="*20)
        self.log("启动智能更新程序")
        self.log("="*20)
        
        # 数据库连接
        conn = self.connect_oracle()
        if not conn:
            self.write_log_file()
            return

        # 数据读取
        df = self.read_excel_data()
        if df is None or df.empty:
            self.log("无有效数据可处理", "WARNING")
            conn.close()
            self.write_log_file()
            return

        # 执行更新
        self.log("开始更新操作...")
        start_time = datetime.now()
        success, total = self.execute_safe_update(conn, df)
        time_used = (datetime.now() - start_time).total_seconds()
        
        # 结果汇总
        self.log("\n操作统计:")
        self.log(f"总记录数: {total}")
        self.log(f"成功更新: {success}")
        self.log(f"失败记录: {total - success}")
        self.log(f"耗时: {time_used:.2f}秒")
        
        # 资源清理
        conn.close()
        self.write_log_file()

if __name__ == "__main__":
    updater = ConditionAwareUpdater()
    try:
        updater.run()
    except Exception as e:
        updater.log(f"程序崩溃: {str(traceback.format_exc())}", "FATAL")
        updater.write_log_file()
    finally:
        # 平台检测与按键处理
        import platform
        if platform.system() == 'Windows':
            import msvcrt
            print("\n操作执行完毕,按任意键退出...")
            msvcrt.getch()  # 捕获任意按键
        else:
            print("\n操作执行完毕,按回车键退出...")
            input()  # Unix系统备用方案

 注:脚本中的信息修改为自己的

涉及到的info文件 ,自行创建一个几个,列名注意修改

 带检测版本,脚本执行完毕后会输出一个日志脚本,如图:

更新时会检测是否满足条件,日志会记录详细执行过程,如下图:

喜欢就留下个赞赞吧!!!

<think>好的,用户想用Python编写连接数据库脚本,特别是MySQL和GBase。我得先回顾一下用户提供的引用内容,看看有哪些有用的信息。引用1提到了使用pymysql和psycopg2库,引用2有具体的连接MySQL的代码示例,引用3则讨论了用Python操作数据库进行结构修改。用户之前可能问过类似的问题,但这次需要具体的示例脚本。 首先,用户可能需要一个基础的连接示例,包括连接、执行查询和关闭连接。然后,考虑到实际应用,可能需要增删改查的操作示例。另外,异常处理也很重要,避免连接失败导致程序崩溃。引用2中的try-except块可以处理连接错误,这点需要包含进去。 用户可能还关心连接不同数据库的方法,比如GBase,虽然引用中没有提到,但GBase通常兼容MySQL协议,所以可能使用同样的pymysql库。需要确认这一点,但根据现有信息,先按MySQL来处理。 然后,是否需要封装成一个类,像引用1中的DataBase类?这样方便复用,用户可能希望看到结构化的代码。所以,示例中可以展示一个简单的类,包含连接、查询、更新等方法。 另外,引用3提到批量修改结构,但用户当前的问题可能不需要这部分,但可以简要提及扩展应用,比如执行DDL语句。 最后,生成相关问题,可能涉及连接参数、游标使用、事务处理等。确保问题覆盖用户可能遇到的下一步疑问。</think>以下是用Python连接MySQL数据库的示例脚本,包含完整的连接、查询和关闭操作流程: ```python import pymysql class DatabaseConnector: def __init__(self, host, user, password, database): self.connection = None try: # 建立数据库连接 self.connection = pymysql.connect( host=host, user=user, password=password, database=database, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor ) print("数据库连接成功") except pymysql.Error as e: print(f"连接失败: {str(e)}") def execute_query(self, sql): """执行查询语句""" try: with self.connection.cursor() as cursor: cursor.execute(sql) result = cursor.fetchall() return result except pymysql.Error as e: print(f"查询失败: {str(e)}") return None def execute_update(self, sql, params=None): """执行更新/插入语句""" try: with self.connection.cursor() as cursor: cursor.execute(sql, params) self.connection.commit() print(f"影响行数: {cursor.rowcount}") return True except pymysql.Error as e: self.connection.rollback() print(f"操作失败: {str(e)}") return False def close(self): """关闭数据库连接""" if self.connection: self.connection.close() print("连接已关闭") # 使用示例 if __name__ == "__main__": # 连接参数配置 config = { "host": "localhost", "user": "root", "password": "123456", "database": "test_db" } db = DatabaseConnector(**config) # 查询示例 query_result = db.execute_query("SELECT * FROM employees LIMIT 5") print("查询结果:", query_result) # 插入示例 insert_sql = "INSERT INTO employees (name, department) VALUES (%s, %s)" db.execute_update(insert_sql, ("张三", "技术部")) db.close() ``` 关键要点说明: 1. 使用`pymysql`库实现MySQL连接(GBase数据库可使用相同协议)[^2] 2. 封装为类结构,支持复用连接和统一异常处理 3. 区分查询和更新操作,自动处理事务提交与回滚 4. 使用上下文管理器管理游标,防止资源泄漏 5. 参数化查询防止SQL注入(注意插入语句中的`%s`占位符)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值