在内存sqlite3数据库中频繁出现“OperationalError:无法打开数据库文件”

时间:2014-01-16 05:43:52

标签: python sqlite

我在内存数据库中使用的是Python应用程序,并且非常频繁且无法打开数据库文件"尝试从多个线程访问内存数据库中的错误时出错。

因为它表示在最后一个连接关闭时自动清理内存数据库,所以我初始化并保持对数据库的连接打开,如下所示:

staging_cache = None

MEMORY_CACHE_PATH = "file::memory:?cache=shared"

def init_staging():
  global staging_cache
  staging_cache = sqlite3.connect(MEMORY_CACHE_PATH)
  staging_cache.execute("""CREATE TABLE sigcache (path TEXT NOT NULL COLLATE NOCASE, sig BLOB,
    updated_date REAL, sha512 TEXT DEFAULT "", item_type INT, depth INT, mtime REAL, size INT, revision_id INT)""")
  staging_cache.execute("CREATE INDEX sigcache_rev_id_index on sigcache(path COLLATE NOCASE, revision_id)")

然后来自其他一些主题:

with sqlite3.connect(MEMORY_CACHE_PATH, timeout=20) as db_conn:
  db_conn.execute(query_string, param_tuple)

好像我一直在遇到OperationalError:无法打开数据库文件

我正在查看http://www.sqlite.org/inmemorydb.html处的文档,但我无法弄清楚我是否做错了。

编辑:显然sqlite3不接受" file :: memory:?cache = shared"作为dbname,它只接受:memory:。它创建了一个名为" file :: memory:?cache = shared"

的文件

无论如何,使用sqlalchemy,持久化数据存在问题。我通过使用sqlite3:memory:,使用check_same_thread = False创建单个连接,并将所有访问包装在单个线程互斥锁中来解决问题。

1 个答案:

答案 0 :(得分:1)

SQLite和多线程混合不好。我建议使用SQLAlchemy的connection pooling(甚至整个包)解决问题。如果你不愿意改写一切,也许就是这样:

import sqlite3
import sqlalchemy.pool

sqlite = sqlalchemy.pool.manage(sqlite3, poolclass=sqlalchemy.pool.SingletonThreadPool)
connection = sqlite.connect(':memory:')

他们还有一些notes about multithreading

  

所以偶数:内存:数据库可以在现代的线程之间共享   SQLite,Pysqlite没有提供足够的线程安全性来实现这一点   用法值得。