SQLAlchemy 和 SQLite:数据库被锁定

新手上路,请多包涵

我有一个使用最新的 sqlalchemy 的 python 脚本。当我使用 sqlite 时,只有 sqlite,其他数据库运行良好,我收到以下错误:

 sqlalchemy.exc.OperationalError: (OperationalError) database is locked u'SELECT blabla....

有什么提示吗?

我的代码示例(简化),我有几种这样的方法来选择、更新和删除内容:

 class MyDb(object):
    def __init__(self):
        engine = create_engine("sqlite:///file", poolclass=NullPool, pool_threadlocal=True)
        engine.pool_size=1
        engine.pool_timeout = 60
        self.sess = sessionmaker(bind=engine)

    def del_stuff(self):
        sess = self.sess()
        sess.query(Stuff).delete()
        try:
            sess.commit()
        except:
            sess.rollback()

    def set_stuff(self, id, bar):
        sess = self.sess()
        sess.query(Foo).get(id).bar = bar
        try:
            sess.commit()
        except:
            sess.rollback()

原文由 tapioco123 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
1 个回答

SQLite 在对数据库进行写操作时锁定数据库,例如发送 UPDATE、INSERT 或 DELETE 时。使用 ORM 时,这些会在刷新时发送。数据库将保持锁定状态,直到出现 COMMIT 或 ROLLBACK。

我经常在多线程情况下看到“数据库已锁定”错误。一个线程将锁定数据库,另一个线程将尝试自己写入。如果第一个线程没有在超时期限内(默认情况下为 4-5 秒,如果我没记错的话)释放锁,则会在第二个线程上引发 OperationalError。

知道何时刷新可能很棘手,因此当会话具有 autoflush=True (默认设置)时写入数据库,因为 任何 查询都会导致刷新。有时打开 SQL 日志记录可以帮助弄清事情发生的时间:

 logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

这里有一些相关文档:http: //docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#database-locking-behavior-concurrency

原文由 Eric Smith 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题