通过我在文档中阅读的所有内容,Django和py-sqlite3都可以使用线程访问.(对吗?)但是这段代码片段对我失败了.主线程中的操作有效,但不在我创建的线程中.在那里我得到:
文件"C:\ Python27\lib\site-packages\django-1.9-py2.7.egg\django\db\backends\sq lite3\base.py",第323行,在执行返回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:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:', # os.path.join(BASE_DIR, 'db.sqlite3'), 'TEST_NAME' : ':memory:', }, }
更新:关于Django的票#12118,我使用相同的症状':memory:'
或磁盘文件(for 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
。如果您不这样做,则线程将看不到其他线程对数据库所做的更改。