我在一个flask应用程序(实际上是connexion)中使用sqlite3
。我希望保留在内存中,但在对服务器的请求之间保留数据库。因此,在服务器被杀死后,它应该被销毁
- 当我使用sqlite3.connect(':memory:')时,每次响应后都会销毁数据库
- 所以我遵循In memory SQLite3 shared database python的方法并运行
sqlite3.connect('file::memory:?cache=shared&mode=memory', uri=True)
。但是,一个名为file::memory:?cache=shared&mode=memory
的文件出现在app根目录中,并且在我终止服务器时没有消失。当我再次启动服务器时,创建表的db-init例程失败,因为表已经创建好了。
我在Linux和Mac上都试过了。两者都有相同的行为。看起来数据库被保存到文件而不是Map到内存。我的python版本是3. 9,sqlite3.sqlite_version_info
是(3,37,0)
1条答案
按热度按时间62lalag41#
我怀疑sqlite把这个
'file::memory:?cache=shared&mode=memory'
当作一个文件名,因此在执行时,会在根目录下创建一个带有这个"名称"的数据库文件。现在的问题,我会尝试连接通过:
为了保持它的活动状态,您可以尝试在开始为应用提供服务之前打开一个连接,将连接对象存储在某个地方,这样它就不会被垃圾收集,然后像往常一样打开和关闭与它的其他连接(基于每个请求)。
SOS:请记住,我只在一个单线程脚本中测试了它,以检查是否有一个新的
sqlite3.connect(':memory:')
连接到我们已经加载的同一个数据库(确实如此)。我不知道它与flask的线程或sqlite本身的配合效果如何。这是我的方法,更多信息如下:
上面的类在我的flask应用程序开始时示例化一次,就在导入之后,如下所示:
这避免了垃圾收集。
要使用,只需调用where is need,如下所示:
您可能已经注意到
self.db = sq.connect(":memory:", check_same_thread=False)
中的第二个参数,这使得使用在不同线程中创建的连接和游标成为可能(如flask),但存在冲突和损坏数据/条目的风险。根据我的理解(关于我的设置flask-〉waiter-〉nginx),除非显式设置为多线程/多处理模式,否则flask将从头到尾处理每个请求,然后继续下一个请求,从而使上述危险变得无关紧要。
我设置了一个基本测试来看看我的理论是否成立。每次请求一个页面时,我都会插入一个递增的数字。然后我在PC、笔记本电脑和移动设备上垃圾刷新。结果164个条目被手动检查完整性并通过。
最后:请记住,我可能遗漏了一些东西,我的方法不是压力测试,也不是我们设置之间的差异。
希望这有帮助!
我建议的第一种方法不能在 flask 中复制。我怀疑这是由于 flask 线程活动。