我在Django中进行了一个简单的集成测试,它生成一个Celery工作者来运行一个作业,该作业将一条记录写入数据库。 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。
答案 0 :(得分:3)
我遇到了同样的问题,我的实验给了我以下内容:
我发现Django在测试模式下使用内存中的SQLite DB,直到您明确更改它为止。这就解释了为什么我只能在单元测试中看到该问题。要强制Django在DATABASES->TEST->NAME
中显式使用文件集settings.py
中的SQLite DB。例如这样的
DATABASES = {
'default': {
...
'TEST': {
'NAME': 'testdb.sqlite3',
},
},
}
将超时值设置为大于2147483.647(看起来很熟悉,对吗?:-))将禁用超时(或将其设置为可忽略的较小值)。
据我了解,问题的根源在于,当SQLite使用共享缓存时,根本不遵守超时值。