![](/img/trans.png)
[英]django.db.utils.OperationalError: no such table in SQLite3 database
[英]Django/sqlite3 “OperationalError: no such table” on threaded operation
根據我在文檔中閱讀的所有內容,Django和py-sqlite3都可以使用線程訪問。 (對嗎?)但是這個代碼片段對我來說失敗了。 主線程中的操作有效,但我創建的線程中的操作無效。 我得到:
在執行返回Database.Cursor.execute(self ,查詢,參數)
OperationalError:沒有這樣的表 :thrtest_mymodel
有什么問題?
我該如何准確跟蹤修補Django的情況或修復它的必要條件? Django的失敗點非常嚴重。 我無法告訴您如何查看它看到的表,或者在主線程和其他線程之間尋找什么區別。
from django.db import models
# Super-simple model
class MyModel(models.Model):
message = models.CharField('Message', max_length=200, blank=True)
#Test
from django.test import TestCase
import time
import threading
import random
done = threading.Event()
nThreads = 1
def InsertRec(msg):
rec = MyModel.objects.create(message=msg)
rec.save()
def InsertThread():
try:
msgNum = 1
thrName = threading.currentThread().name
print 'Starting %s' % thrName
while not done.wait(random.random() * 0.1):
msgNum += 1
msg = '%s: %d' % (thrName, msgNum)
print msg
InsertRec(msg)
finally:
done.set()
pass
class ThreadTestRun(TestCase):
def testRunIt(self):
nThisThread = 10
msgSet = set()
for x in xrange(nThisThread):
msg = 'Some message %d' % x
InsertRec(msg) # From main thread: works!
msgSet.add(msg)
self.assertEqual(MyModel.objects.count(), nThisThread)
# We use sets because .all() doesn't preserve the original order.
self.assertEqual(msgSet, set([r.message for r in MyModel.objects.all()]))
thrSet = set()
for thrNum in xrange(nThreads):
t = threading.Thread(name='Thread %d' % thrNum, target=InsertThread)
t.start()
thrSet.add(t)
done.wait(10.)
done.set()
for t in thrSet:
t.join()
更新 :這是來自settings.py的數據庫:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:', # os.path.join(BASE_DIR, 'db.sqlite3'),
'TEST_NAME' : ':memory:',
},
}
更新 :關於Django的票證#12118,我使用':memory:'
或磁盤文件(用於TEST_NAME
)得到相同的症狀。
Django 1.9,Python 2.7.11。 (與Django 1.6中的症狀相同。)
像這樣更改您的DATABASES
:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:',
'TEST' :
{
'NAME': 'test_db',
}
},
}
這將迫使django在磁盤上創建一個真正的sqlite db,而不是在內存中創建它。
另外,還要確保從django.test.testcases.TransactionTestCase
繼承與線程相關的測試用例。 如果您不這樣做,則這些線程將看不到其他線程對數據庫所做的更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.