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