Issue: Fixed thread_locals not actually working.
Author: b1naryth1ef
State: closed
Created: 2012-06-22 17:18:46

Cheap fix that you may feel like rewriting to actually trace back to the problem. The thread_locals var was being passed in as connect_kwargs as opposed to the keyword. 

Again, this is probably just a temporary fix.


How does this come about?  How is it being passed in via connect_kwargs?


Hmm, i'm kind of baffled -- where is "self.threadlocals" referenced?  In my code it appears that it is just used in the scope of the init method, where the `__local` is instantiated.  Can you explain more the rationale?


I was consistently having problems with starting an sqlite instance, and giving it the threadlocals var. Tested on both 2.6/2.7 and few os's. Looked into it, and it seems threadlocals wasnt actually being passed in under the threadlocals kwarg, but rather inside the *\* catch all. Again, this isnt really a proper fix to it. 


Ahhh never mind, I see. The `self.` isnt required. This was more of a fix of threadlocals not being passed correctly.


can you please send me your code that was not working properly so i can test it here?  i've not encountered this problem myself.


```
from peewee import *
import thread

db = SqliteDatabase('test', threadlocals=True)
db.connect()

class Test():
    uid = IntegerField()

Test.create_table()

t = Test(1)
t.save()

q = lambda: [i for i in Test.select().where(uid=1)

thread.start_new_thread(q, ())
```

Something like that.


Sorry but that code has a number of problems.  you're not specifying your database when you define your model.  your model doesn't subclass Model.  I'm also not clear on how that demonstrates the actual issue.


Sorry wrote that on the fly. This code gives the error:

```
from peewee import *
import thread

db = SqliteDatabase('test.db', threadlocals=True)
db.connect()

class Test(model):
    uid = IntegerField()

Test.create_table()

t = Test(uid=1)
t.save()

def testQuery():
    print [i for i in Test.select().where(uid=1)]

thread.start_new_thread(testQuery, ())
```

The example outputs this on both a Mac laptop and Linux box:

```
-1214440592
Unhandled exception in thread started by <function testing at 0xb7bffbfc>
Traceback (most recent call last):
  File "<stdin>", line 2, in testing
  File "/usr/local/lib/python2.6/dist-packages/peewee-0.9.7-py2.6.egg/peewee.py", line 1646, in __iter__
    return iter(self.execute())
  File "/usr/local/lib/python2.6/dist-packages/peewee-0.9.7-py2.6.egg/peewee.py", line 1638, in execute
    self._qr = QueryResultWrapper(self.model, self.raw_execute(sql, params), meta)
  File "/usr/local/lib/python2.6/dist-packages/peewee-0.9.7-py2.6.egg/peewee.py", line 1287, in raw_execute
    return self.database.execute(query, params, self.require_commit)
  File "/usr/local/lib/python2.6/dist-packages/peewee-0.9.7-py2.6.egg/peewee.py", line 322, in execute
    cursor = self.get_cursor()
  File "/usr/local/lib/python2.6/dist-packages/peewee-0.9.7-py2.6.egg/peewee.py", line 319, in get_cursor
    return self.get_conn().cursor()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread.The object was created in thread id -1211824448 and this is thread id -1214440592
```

The problem is passing threadlocals into peewees Database class, as I mentioned a few comments above.


You need to tell peewee to use the database you instantiated:

``` python

class Test(model):
    uid = IntegerField()

    class Meta:
        database = db
```


And now I fell silly! My only note is that this is a just little unclear/ambiguous in the docs. Might consider moving the `Best Practices` up a bit, or make it more clear that its important/required. Thanks much for your help!


No sweat, mane -- i'll spruce up the docs.  This works fine for me, btw:

``` python

from peewee import *
import threading

db = SqliteDatabase('test.db', threadlocals=True)
db.connect()

class Test(Model):
    uid = IntegerField()
    class Meta:
        database=db

Test.create_table(True)

t = Test(uid=1)
t.save()

def testQuery():
    print [i for i in Test.select().where(uid=1)]

t = threading.Thread(target=testQuery)
t.start()
t.join()
```