2016-01-07 30 views
5

Di tutto ciò che ho letto nei documenti, sia Django che py-sqlite3 dovrebbero andare bene con accesso filettato. (Giusto?) Ma questo frammento di codice fallisce per me. Le operazioni nel thread principale funzionano, ma non nel thread (i) che creo. Lì ottengo:Django/sqlite3 "OperationalError: no such table" sull'operatività con thread

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

Qual è il problema?

Come faccio a rintracciare esattamente cosa sta succedendo per correggere Django o qualsiasi cosa sia necessaria per risolverlo? Il punto di fallimento in Django è piuttosto indistrante. Non posso dire come vedere quali tabelle vede, o quali differenze cercare tra main e altri thread.

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() 

Aggiornamento: Ecco database dal settings.py:

DATABASES = { 
    'default': { 
     'ENGINE': 'django.db.backends.sqlite3', 
     'NAME': ':memory:', # os.path.join(BASE_DIR, 'db.sqlite3'), 
     'TEST_NAME' : ':memory:', 
    }, 
} 

Aggiornamento: Per quanto riguarda il biglietto di Django # 12118, ottengo gli stessi sintomi utilizzando ':memory:' o un file su disco (per TEST_NAME).

Django 1.9, Python 2.7.11. (Stessi sintomi in Django 1.6.)

+0

Che aspetto hanno le impostazioni dei DATABASE? –

+0

Questo sembra correlato, anche se sembra essere risolto in 1.8.xe 1.9.x. https://code.djangoproject.com/ticket/12118 – Krab

risposta

3

cambiare la vostra DATABASES in questo modo:

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

Questo costringerà Django per creare un vero e proprio db sqlite sul disco, invece di creare nella memoria.

Assicurarsi inoltre di ereditare i casi di test relativi al threading da django.test.testcases.TransactionTestCase. Se non lo fai, i thread non vedranno le modifiche al database fatte da altri thread.

+0

Grazie per la risposta. Ma questa è una delle configurazioni che ho provato (ultimo aggiornamento sopra: la versione precedente di django utilizza "TEST_NAME" e "TEST": {'NOME': ...}). I test che controllano solo qualcosa e finiscono tutto vanno bene, ma il mio test multithreading che viene eseguito un po 'all'improvviso nel mezzo indica che il database è cambiato e che tutti i tavoli sono spariti. Come il database è stato automaticamente ripristinato. – JimB

+0

strano:/come ultima opzione puoi dire a django di mantenere il database dopo il test con la chiave '--keepdb'. – eviltnan

+0

hai salvato il mio giorno –