首页 > 解决方案 > 在 Python 中围绕函数“包装”数据库的打开和关闭的好方法?

问题描述

我查看了有关 StackOverflow 的一些相关问题以及有关包装器的一些文档/指南,所有这些都告诉我“不”,但这似乎不对。也就是说,我对编程很陌生,所以 ‍♂️</p>

问题:打开和关闭数据库(使用 python/sqlite3)需要大量重复的代码(据我了解):

connection = None
connection = sqlite3.connect(path)
conn.execute("bla bla bla")
conn.commit()
conn.close()

因此,我尝试为访问数据库的函数编写一个可重用的包装器。但这并不理想,到目前为止,主要是使代码复杂化(稍后讨论的问题):

import functools
import sqlite3 
from sqlite3 import Error


conn = None         # a global that I hope to get rid of soon.  

def connect_db(function):
    """
    wrapper that should open db, performs function, then closes db
    """
    global conn
    try:
        conn = sqlite3.connect("journ.db")
        print("connected")
    except:
        print("problem")

    @functools.wraps(function)
    def wrapper(*args, **kwargs):
        return function(*args, **kwargs)
        # conn.close()  # unreachable code!!
    return wrapper

@connect_db
def find_entry_info(user_id):
    """
    Queries database regarding users' entries and returns a dictionary (k=entry_url, v=[date, time]).
    """
    entry_info = {}
    # entry_tags = {}
    db_handler = conn.execute("SELECT entry_url, date, time FROM entries WHERE user_id=? ORDER BY date DESC, time DESC",
                        user_id
                            )
    for row in db_handler:
        entry_info[row[0]]=[row[1], row[2]]
    return entry_info

entry_info = find_entry_info(user_id)

我现在知道的问题:

  1. conn是一个全局变量,经典的“坏主意”。我有信心最终能解决这个问题,但我更专注于以下方面:
  2. 根据文档,在从包装函数返回所需值后,无法关闭包装器中的数据库。当然,我可以在包装函数中关闭它,但这违背了包装器的要点,并且并不比调用常规函数打开数据库更好。

那么,是否有一种聪明/简单的方法来编写打开/关闭数据库的包装器?我想念的流行图书馆?我是否应该尝试查看 python 类。. . 或者只是接受围绕我的查询的混乱?提前感谢大家的时间和善意。

标签: pythondatabasesqlitedecoratorwrapper

解决方案


连接可以用作上下文管理器,在出现异常时自动提交事务或回滚:

with sqlite3.connect(path) as conn:
    conn.execute(query)

连接也将在最后自动关闭。


推荐阅读