我正在使用 peewee 访问 SQLite 数据库。
我做了一个
model.py
,例如:
from peewee import *
db = SqliteDatabase('people.db')
class Person(Model):
name = CharField()
birthday = DateField()
is_relative = BooleanField()
class Meta:
database = db
在另一个Python文件(带有
import model
)中,我然后使用诸如Person.create()
或Person.select(name=='Joe').delete_instance()
之类的调用来操作数据库。
快速入门最后表示调用
db.close()
来关闭连接。这也适用于我的情况吗?我应该称呼类似model.db.close()
之类的东西吗?
根据 peewee 的制造者Charles Leifer的说法,终止连接是程序员的工作。关于连接池的文档告诉我们,所有连接都是线程本地的,因此只要模型正在使用,连接就会保持打开状态,并在包含事务的线程加入主线程时终止。
Charles 明确回答了有关连接池的问题。答案有点笼统,但我认为这同样适用于所有连接:关于连接池
主题的隐含答案:
摘自文档快速入门页面:
虽然没有必要显式打开连接,但这是一个很好的做法,因为它会立即显示数据库连接的任何错误,而不是在执行第一个查询后的任意时间。 完成后关闭连接也很好 – 例如,Web 应用程序可能会在收到请求时打开连接,并在发送响应时关闭连接。
根据这些信息,您问题的最终答案是:否。
您手动打开和关闭连接:
就您而言(带有
db = SqliteDatabase('people.db')
)
您通过以下方式建立了与数据库的连接:
db.connect()
接下来,您可以对数据库执行任何您想要的操作,最后关闭连接:
db.close()
追踪现有项目中未正确关闭的数据库连接可能非常具有挑战性。这是我的方法,供遇到同样问题的人参考:
使用 Python 2.7 实现,我在销毁 Peewee 模型期间检查数据库连接。如果连接保持打开状态,则会发出警告以及回溯;但是,
with database:
上下文中的场景会被绕过。
from playhouse.pool import PooledMySQLDatabase
from peewee import Model
import logging
import traceback
logger = logging.getLogger(__name__)
class TrackingDatabase(PooledMySQLDatabase):
def __init__(self, *args, **kwargs):
super(TrackingDatabase, self).__init__(*args, **kwargs)
self._in_context = False
def __enter__(self):
self._in_context = True
return super(TrackingDatabase, self).__enter__()
def __exit__(self, exc_type, exc_val, exc_tb):
self._in_context = False
return super(TrackingDatabase, self).__exit__(exc_type, exc_val, exc_tb)
@property
def in_context(self):
return self._in_context
database = TrackingDatabase(....)
class BaseModel(Model):
class Meta:
database = database
def __del__(self):
if not database.is_closed() and not database.in_context:
stack = "".join(traceback.format_stack())
logger.warning("Database connection remains open.\n%s", stack)
然后将警告部分包装在
with database:
上下文中,以确保连接正确关闭。