我正在编写我的第一个SQLAlchemy(0.6.8)/ Python(2.7.1)程序,它位于SQLite(我认为是3.7.6.3)之上,在Windows Vista上运行。
为了执行单元测试,我将SQLite指向测试数据库,我的单元测试脚本会定期删除数据库文件,所以我一直在使用已知的初始状态。
有时我的(单线程)单元测试无法删除文件:
WindowsError: [Error 32] The process cannot access the file because it is being used by another process
使用该文件的唯一进程是单元测试工具。很明显,我的一个已完成的单元测试没有释放某些锁,阻止了同一进程中的下一个单元测试删除文件。
我搜索了我创建会话的所有地方,并确认有相应的session.commit()或session.rollback()。
我在我的代码中搜索了所有session.commit()和session.rollback()调用,之后立即添加了一个session.close()调用,试图显式释放任何事务锁,但它没有'帮助。
是否有任何秘密可以确保在事务结束时删除剩余的锁以允许删除文件?
答案 0 :(得分:4)
有人遇到类似的问题:http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg20724.html
您应该在连接建立时使用NullPool,以确保在session.close()
之后没有活动连接
from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool
to_engine = create_engine('sqlite:///%s' % temp_file_name, poolclass=NullPool)
参考:http://www.sqlalchemy.org/docs/06/core/pooling.html?highlight=pool#sqlalchemy.pool
只有在0.7.0之前的SQLAlchemy中才需要这样做。在0.7.0之后,这成为SQLite的默认行为。参考:http://www.sqlalchemy.org/docs/core/pooling.html?highlight=pool#sqlalchemy.pool
答案 1 :(得分:1)
您是否需要在单元测试期间对数据库进行共享访问?如果没有,请使用内存中的SQLite数据库进行这些测试。来自SQLAlchemy documentation:
如果没有文件路径,则sqlite:memory:identifier是默认值。指定sqlite://而不是其他:
# in-memory database e = create_engine('sqlite://')
无需管理临时文件,无需锁定语义,保证单元测试之间的清晰等等。