Hi,

Please consider this example:

#!/usr/bin/env python

import apsw
import tempfile

fh = tempfile.NamedTemporaryFile()
conn = apsw.Connection(fh.name)

# Fill the db with some data
cur = conn.cursor()
datafh = open("/dev/urandom", "rb")
cur.execute("CREATE TABLE foo (no INT, data BLOB)")
for i in range(42):
    cur.execute("INSERT INTO foo(no,data) VALUES(?,?)", (i, buffer(datafh.read(4096))))
del cur    

# Here comes the problem:
def dostuff(conn, fail):
    cur = conn.cursor()
    # Ignore result, we just need to make some query
    cur.execute("SELECT data FROM foo WHERE no = ?", (33,))
    cur2 = conn.cursor()
    
    if fail:
        raise TypeError
    else:
        return
    
# This works:
dostuff(conn, fail=False)
cur = conn.cursor()
cur.execute("VACUUM")
#cur.execute("CREATE TABLE test (no INT)")

# This does not:
try:
    dostuff(conn, fail=True)
except TypeError:       
    cur = conn.cursor()
    cur.execute("VACUUM")
    #cur.execute("CREATE TABLE test2 (no INT)")

While the first execute("VACUUM") call succeeds, the second does not but
raises an apsw.BusyError (meaning that sqlite thinks that it cannot get
an exclusive lock on the database).

I suspect that the reason for that is that the cursor object that is
created in the function is not destroyed when the function is left with
raise (rather than return), which in turn prevents sqlite from obtaining
the lock.

However, if I exchange the VACUUM command by something else (e.g. CREATE
TABLE), the program runs fine. I think this casts some doubt on the
above explanation, since, AFAIK sqlite always locks the entire file and
should therefore have the some problem as before.


Can someone explain what exactly is happening here?


Best,


   -Nikolaus

-- 
 »Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to