views:

597

answers:

6

I'm coding a small piece of server software for the personal use of several users. Not hundreds, not thousands, but perhaps 3-10 at a time.

Since it's a threaded server, SQLite doesn't work. It complains about threads like this:

ProgrammingError: SQLite objects created in a thread can only be used in that same thread.The object was created in thread id 140735085562848 and this is thread id 4301299712

Besides, they say SQLite isn't great for concurrency anyhow.

Now since I started working with Python 3 (and would rather continue using it) I can't seem to get the MySQL module to work properly and others seem equally frustrated.

In that case, is there any other DB option for Python 3 that I could consider?

+1  A: 

I did a port of psycopg2 to Python 3.

Martin v. Löwis
A: 

couchdb-python.

Zed
Could you link to the Python 3 version? Because I can't find one.
Lennart Regebro
A: 

You could create a new sqlite object in each thread, each using the same database file. For such a small number of users you might not come across the problems with concurrency, unless they are all writing to it very heavily.

Tom Haigh
I thought about that. But then again there's the problem that they could potentially. I'm not entirely sure just how heavily they'll write to it.
Adi
+5  A: 

First note that sqlite is thread safe

$ python
Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite
>>> sqlite.threadsafety
1

Then just make sure you open a new handle to the database in each thread.

I do this using thread local storage to cache the database handle so there is only one per thread. Something like this... (from a py2.5 prog - hopefully it will work with 3.0!)

import threading

class YourClass:
    def __init__(self):
        #...
        self.local = threading.local()  # Thread local storage for db handles
        self.db_file = "/path/to/db"
        #...
    def db_open(self):
        if not getattr(self.local, "db", None):
            self.local.db = sqlite3.connect(self.db_file)
        return self.local.db
Nick Craig-Wood
That's interesting, I've been told it supposedly wasn't thread safe. Good to know it is. :)
Adi
A: 

I know there is some Python driver for Firebird but I don't know if some exist for Python 3. May be you can ask in the Firebird-Python support list

Hugues Van Landeghem
A: 

Surely a pragmatic option is to just use one SQLite connection per thread.

MarkR