【发布时间】:2018-03-31 14:28:21
【问题描述】:
我在 Django 中有一个简单的集成测试,它生成一个 Celery worker 来运行一个作业,它将一条记录写入数据库。 Django 线程还将记录写入数据库。因为是测试,所以我使用默认的内存中 sqlite3 数据库。没有正在使用的事务。
我经常收到这个错误:
django.db.utils.OperationalError: database table is locked
根据 Django 文档,这是由于一个连接在等待另一个连接完成时超时。它是“比 sqlite 在默认配置中可以处理的更多并发”。这似乎很奇怪,因为它是两个线程中的两个记录。尽管如此,相同的文档说增加超时选项以强制连接等待更长时间。好的,我将我的数据库设置更改为:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'OPTIONS': {'timeout': 10000000},
}
}
这没有效果。错误仍然出现,并且在这样做之前显然没有等待 1e7 秒或 1e7 毫秒或 1e7 微秒。我还缺少其他设置吗?
我已经尝试过 Python 3.5 和 Python 3.6 以及 Django 1.11 和 Django 2.0。
【问题讨论】:
-
我在 Python 3.4/Django 1.10 上看到了同样的行为。
-
在我看来这是 python/sqlite 的问题。我确认 django 按照 sqlite3 python 文档正确传递了配置的超时值。它似乎根本不等待我,好像等待锁定已完全禁用。您是否偶然在 Windows 上运行?
-
我的实验给了我以下信息: 1. 因为问题只有在我运行测试时才会出现。我发现 Django 在测试模式下使用内存中的 SQLite DB,直到
TEST->NAME设置为:'TEST': {'NAME': 'testdb.sqlite3'}。 2. 将timeout的值设置为大于2147483.647(看起来很熟悉,对吗?:-))禁用超时(或将其设置为可忽略不计的小值)。 3.据我了解,原始错误的原因是使用 SQLite shared cache 时根本不遵守超时值。 -
@prokher:如果您的评论可以解决问题中描述的问题,您能否回答?
-
@FrederickNord 完成。