You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设计无重复连接代码的Python/SQLite应用?

优化方案:抽象数据库层与业务基类

针对你当前的代码重复、数据库耦合问题,以下是符合DRY原则且易于扩展的解决方案:

1. 封装数据库操作工具类(消除重复连接逻辑)

创建统一的数据库操作抽象层,把连接创建、SQL执行、事务处理等重复逻辑封装起来,所有业务类共用这个工具类,彻底避免重复写连接代码。

import sqlite3
from abc import ABC, abstractmethod

# 数据库操作抽象基类,定义统一接口
class BaseDatabaseHandler(ABC):
    @abstractmethod
    def connect(self):
        pass

    @abstractmethod
    def execute(self, query, params=None):
        pass

# SQLite具体实现类
class SQLiteHandler(BaseDatabaseHandler):
    def __init__(self, db_path):
        self.db_path = db_path
        self.conn = None

    def connect(self):
        # 保持长连接,避免重复创建连接
        if not self.conn:
            self.conn = sqlite3.connect(self.db_path)
        return self.conn

    def execute(self, query, params=None):
        conn = self.connect()
        cur = conn.cursor()
        try:
            if params:
                cur.execute(query, params)
            else:
                cur.execute(query)
            conn.commit()
            # 返回查询结果(如果有)
            return cur.fetchall() if cur.description else None
        except Exception as e:
            conn.rollback()
            raise e
        finally:
            # 可根据需求选择是否关闭游标/连接,SQLite默认连接管理更灵活
            cur.close()

# 全局实例化,所有业务类共享同一个数据库连接
db_handler = SQLiteHandler("mydb.db")

2. 抽象业务对象基类(复用CRUD逻辑)

创建业务对象基类,封装通用的保存、删除、更新方法。具体业务类只需提供表名、字段映射等专属信息,无需重复编写CRUD代码。

class BaseBusinessObject:
    def __init__(self, db_handler):
        self.db_handler = db_handler
        # 子类必须重写以下属性
        self.table_name = ""
        self.fields = []  # 例如 ["id", "name", "status"]

    def save_to_db(self):
        # 根据id判断是新增还是更新
        if hasattr(self, "id") and self.id is not None:
            # 更新逻辑
            set_clause = ", ".join([f"{field} = ?" for field in self.fields if field != "id"])
            query = f"UPDATE {self.table_name} SET {set_clause} WHERE id = ?"
            params = [getattr(self, field) for field in self.fields if field != "id"] + [self.id]
        else:
            # 新增逻辑
            placeholders = ", ".join(["?" for _ in self.fields])
            query = f"INSERT INTO {self.table_name} ({', '.join(self.fields)}) VALUES ({placeholders})"
            params = [getattr(self, field) for field in self.fields]
        
        self.db_handler.execute(query, params)
        # 新增时自动获取自增id
        if not hasattr(self, "id") or self.id is None:
            self.id = self.db_handler.execute("SELECT last_insert_rowid()")[0][0]

    def delete_from_db(self):
        if not hasattr(self, "id") or self.id is None:
            raise ValueError("无法删除未设置id的对象")
        query = f"DELETE FROM {self.table_name} WHERE id = ?"
        self.db_handler.execute(query, (self.id,))

# 具体业务类示例
class BusinessObject1(BaseBusinessObject):
    def __init__(self, db_handler, id=None, name=None, value=None):
        super().__init__(db_handler)
        self.table_name = "business_object1"
        self.fields = ["id", "name", "value"]
        self.id = id
        self.name = name
        self.value = value

class BusinessObject2(BaseBusinessObject):
    def __init__(self, db_handler, id=None, code=None, description=None):
        super().__init__(db_handler)
        self.table_name = "business_object2"
        self.fields = ["id", "code", "description"]
        self.id = id
        self.code = code
        self.description = description

3. 支持多数据库切换(解耦数据库依赖)

后续需要切换到MySQL或PostgreSQL时,只需新增对应数据库的BaseDatabaseHandler实现类,替换全局的db_handler实例即可,业务代码完全无需修改。

示例MySQL实现框架:

import mysql.connector

class MySQLHandler(BaseDatabaseHandler):
    def __init__(self, host, user, password, db_name):
        self.host = host
        self.user = user
        self.password = password
        self.db_name = db_name
        self.conn = None

    def connect(self):
        if not self.conn:
            self.conn = mysql.connector.connect(
                host=self.host,
                user=self.user,
                password=self.password,
                database=self.db_name
            )
        return self.conn

    def execute(self, query, params=None):
        conn = self.connect()
        cur = conn.cursor()
        try:
            if params:
                cur.execute(query, params)
            else:
                cur.execute(query)
            conn.commit()
            return cur.fetchall() if cur.description else None
        except Exception as e:
            conn.rollback()
            raise e
        finally:
            cur.close()

# 切换数据库时替换实例即可
# db_handler = MySQLHandler("localhost", "root", "password", "mydb")

4. 统一维护全局对象信息表

在BaseBusinessObject中添加全局日志逻辑,每次保存/删除对象时,自动同步更新全局对象信息表:

class BaseBusinessObject:
    # 原有代码...

    def save_to_db(self):
        # 原有保存逻辑...
        self._update_global_object_log("save")

    def delete_from_db(self):
        # 原有删除逻辑...
        self._update_global_object_log("delete")

    def _update_global_object_log(self, operation):
        from datetime import datetime
        # 假设全局表名为object_log,字段:id, object_type, object_id, operation_time, operation
        query = """
            INSERT INTO object_log (object_type, object_id, operation_time, operation)
            VALUES (?, ?, ?, ?)
        """
        params = (self.table_name, self.id, datetime.now().isoformat(), operation)
        self.db_handler.execute(query, params)

内容的提问来源于stack exchange,提问作者Saalim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:57:38