SQLAlchemy和SQLite:数据库被锁定

tap*_*123 8 python sqlite sqlalchemy python-2.7

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

sqlalchemy.exc.OperationalError: (OperationalError) database is locked u'SELECT blabla....
Run Code Online (Sandbox Code Playgroud)

任何提示?

我的代码(简化)示例,我有几个像这样的方法来选择,更新和删除东西:

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()
Run Code Online (Sandbox Code Playgroud)

Eri*_*ith 17

SQLite在对数据库进行写入时锁定数据库,例如在发送UPDATE,INSERT或DELETE时.使用ORM时,这些将在flush上发送.在存在COMMIT或ROLLBACK之前,数据库将保持锁定状态.

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

知道何时刷新并因此在会话具有autoflush=True(默认设置)时对数据库进行写入可能是棘手的,因为任何查询都将导致刷新.有时打开SQL日志记录可以帮助澄清事情何时发生:

logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
Run Code Online (Sandbox Code Playgroud)

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


Bin*_*ese 10

通过任何开发人员工具检查数据库中任何待处理的提交。

正如上面每个人所说的那样,sqlite 数据库一次只允许一个进程访问它。就我而言,我使用SQLite 的数据库浏览器,同样,我没有提交查询。这也会锁定数据库,并且不允许应用程序写入数据库。


Y.H*_*ong 5

sqlite 数据库一次只允许一个进程访问它。也许你有一个单独的进程使用数据库?


小智 5

就我而言,逻辑非常简单并且没有多线程,问题的根源似乎相当平庸......

\n\n
\n

“SQLite 并不是为高水平的写入并发性而设计的。数据库本身作为一个文件,在事务内的写入操作期间被完全锁定,这意味着恰好一个 \xe2\x80\x9cconnection\xe2\x80\x9d(实际上是一个文件句柄)具有对在此期间的数据库 - 所有其他 \xe2\x80\x9c 连接\xe2\x80\x9d 将在此\n 时间内被阻止。

\n
\n\n

...这样“启发”了一个想法:断开我在工作期间用来检查数据库的数据库浏览器。\n而且效果很好。\n因此,如果这可能是您的情况 - 检查您是否没有通过其他工具连接到您的 sqlite ;)

\n