当前位置:  开发笔记 > 编程语言 > 正文

关于线程操作的Django/sqlite3"OperationalError:no such table"

如何解决《关于线程操作的Django/sqlite3"OperationalError:nosuchtable"》经验,为你挑选了1个好方法。

通过我在文档中阅读的所有内容,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中的症状相同.)



1> eviltnan..:

DATABASES像这样更改您的:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': ':memory:',
        'TEST' : 
            {
                'NAME': 'test_db',
            }
    },
}

这将迫使django在磁盘上创建一个真正的sqlite db,而不是在内存中创建它。

另外,请务必从继承与线程相关的测试用例django.test.testcases.TransactionTestCase。如果您不这样做,则线程将看不到其他线程对数据库所做的更改。

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有