views:

481

answers:

2

Hi,

I have a Python application which throws the standard sqlite3.OperationalError: database is locked error. I have looked around the internet and could not find any solution which worked (please note that there is no multiprocesses/threading going on, and as you can see I have tried raising the timeout parameter). The sqlite file is stored on the local hard drive.

The following function is one of many which accesses the sqlite database, and runs fine the first time it is called, but throws the above error the second time it is called (it is called as part of a for loop in another function):

def update_index(filepath):
    path = get_setting('Local', 'web')
    stat = os.stat(filepath)
    modified = stat.st_mtime
    index_file = get_setting('Local', 'index')

    connection = sqlite3.connect(index_file, 30)
    cursor = connection.cursor()
    head, tail = os.path.split(filepath)
    cursor.execute('UPDATE hwlive SET date=? WHERE path=? AND name=?;', (modified, head, tail))
    connection.commit()
    connection.close()

Many thanks.

A: 

Do you really need to continuously open and close the database file for every single UPDATE? If you do the same thing in every function that accesses the database, is it possible that you have called the update_index function from another function that already opened the database using a different connection and is in the process of modifying the database?

ΤΖΩΤΖΙΟΥ
The database should be fully closed before this function is called. If I were to keep the database connection open, what would be the best method? Store the `connection` instance outside the scope of the function, or pass it as a parameter?
James C
It would be tidier if you made a class, put all the functions dealing with the database in the class, have the connection as a member attribute of the class. You can create the connection in the class `__init__` and add a `close_connection` (with obvious content) method that you call when you're done. Otherwise, you can search your code and add debugging statements whenever you open and close a connection to the database, see if they are nested.
ΤΖΩΤΖΙΟΥ
A: 

You might particularly check for functions that keep a read-lock (unfinished cursor). That would block the commit from the update function. Note that there is a dedicated mailing list for Python-sqlite problems: http://groups.google.com/group/python-sqlite