"wrap" 围绕 Python 中的函数打开和关闭数据库的好方法?
Good way to "wrap" the opening and closing of a database around functions in Python?
我查看了 Whosebug 上的一些相关问题以及一些 documentation/guides 关于包装器的问题,所有这些都告诉我“不”,但这似乎不正确。也就是说,我对编程很陌生,所以 ♂️
问题:打开和关闭数据库(使用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)
我目前知道的问题:
conn
是一个全局变量,经典的“坏主意”。我有信心最终能解决这个问题,但我更关注以下几点:
- 根据文档,无法在从包装函数返回所需值后关闭包装器内的数据库。
当然,我可以在包装函数中关闭它,但这违背了包装器的要点,并且并不比调用常规函数打开数据库更好。
那么,是否有 clever/simple 方法来编写 opens/closes 数据库的包装器?我缺少一个受欢迎的图书馆?我应该尝试查看 python 类 吗? . .或者只是接受围绕我的查询的混乱?预先感谢大家的时间和善意。
连接可用作context managers,在出现异常时自动提交事务或回滚:
with sqlite3.connect(path) as conn:
conn.execute(query)
最后连接也会自动关闭
我查看了 Whosebug 上的一些相关问题以及一些 documentation/guides 关于包装器的问题,所有这些都告诉我“不”,但这似乎不正确。也就是说,我对编程很陌生,所以 ♂️
问题:打开和关闭数据库(使用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)
我目前知道的问题:
conn
是一个全局变量,经典的“坏主意”。我有信心最终能解决这个问题,但我更关注以下几点:- 根据文档,无法在从包装函数返回所需值后关闭包装器内的数据库。 当然,我可以在包装函数中关闭它,但这违背了包装器的要点,并且并不比调用常规函数打开数据库更好。
那么,是否有 clever/simple 方法来编写 opens/closes 数据库的包装器?我缺少一个受欢迎的图书馆?我应该尝试查看 python 类 吗? . .或者只是接受围绕我的查询的混乱?预先感谢大家的时间和善意。
连接可用作context managers,在出现异常时自动提交事务或回滚:
with sqlite3.connect(path) as conn:
conn.execute(query)
最后连接也会自动关闭