python - Django/sqlite3 "OperationalError: no such table" on threaded operation -
by read in docs, both django , py-sqlite3 should fine threaded access. (right?) code snippet fails me. operations in main thread work, not in thread(s) create. there get:
file "c:\python27\lib\site-packages\django-1.9-py2.7.egg\django\db\backends\sq lite3\base.py", line 323, in execute return database.cursor.execute(self, query, params)
operationalerror: no such table: thrtest_mymodel
what's problem?
how go tracking down what's happening patch django or whatever's necessary fix it? point of failure in django pretty indimidating. can't tell how see tables see, or differences between main , other threads.
from django.db import models # super-simple model class mymodel(models.model): message = models.charfield('message', max_length=200, blank=true) #test 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() x in xrange(nthisthread): msg = 'some message %d' % x insertrec(msg) # main thread: works! msgset.add(msg) self.assertequal(mymodel.objects.count(), nthisthread) # use sets because .all() doesn't preserve original order. self.assertequal(msgset, set([r.message r in mymodel.objects.all()])) thrset = set() thrnum in xrange(nthreads): t = threading.thread(name='thread %d' % thrnum, target=insertthread) t.start() thrset.add(t) done.wait(10.) done.set() t in thrset: t.join()
update: here databases settings.py:
databases = { 'default': { 'engine': 'django.db.backends.sqlite3', 'name': ':memory:', # os.path.join(base_dir, 'db.sqlite3'), 'test_name' : ':memory:', }, }
update: respect django's ticket #12118, same symptoms using ':memory:'
or disk file (for test_name
).
django 1.9, python 2.7.11. (same symptoms in django 1.6.)
change databases
this:
databases = { 'default': { 'engine': 'django.db.backends.sqlite3', 'name': ':memory:', 'test' : { 'name': 'test_db', } }, }
this force django create real sqlite db on disk, instead of creating in memory.
also sure inherit test cases related threading django.test.testcases.transactiontestcase
. if don't so, threads won't see database changes made threads.
Comments
Post a Comment