SQLite3,带文件夹内存模式

yshpjwxd  于 2023-01-21  发布在  SQLite
关注(0)|答案(1)|浏览(186)

我在一个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)

62lalag4

62lalag41#

我怀疑sqlite把这个'file::memory:?cache=shared&mode=memory'当作一个文件名,因此在执行时,会在根目录下创建一个带有这个"名称"的数据库文件。
现在的问题,我会尝试连接通过:

sqlite3.connect(':memory:')

为了保持它的活动状态,您可以尝试在开始为应用提供服务之前打开一个连接,将连接对象存储在某个地方,这样它就不会被垃圾收集,然后像往常一样打开和关闭与它的其他连接(基于每个请求)。
SOS:请记住,我只在一个单线程脚本中测试了它,以检查是否有一个新的sqlite3.connect(':memory:')连接到我们已经加载的同一个数据库(确实如此)。我不知道它与flask的线程或sqlite本身的配合效果如何。

    • 更新日期:**

这是我的方法,更多信息如下:

class db_test:
    # DOES NOT INCLUDE LOADING THE FILE TO MEMORY AND VICE VERSA (out of the scope of the question)
    def __init__(self):
        self.db = sqlite3.connect(":memory:", check_same_thread=False)

    def execute_insert(self, query: str, data: tuple):
        cur = self.db.cursor()
        with self.db:
            cur.execute(query, data)
        cur.close()

上面的类在我的flask应用程序开始时示例化一次,就在导入之后,如下所示:

from classes import db_test
db = db_test()

这避免了垃圾收集。
要使用,只需调用where is need,如下所示:

@app.route("/db_test")
def db_test():
    db.execute_insert("INSERT INTO table (entry) VALUES (?)", ('hello', ))
    return render_template("db_test.html")
    • 注:**

您可能已经注意到self.db = sq.connect(":memory:", check_same_thread=False)中的第二个参数,这使得使用在不同线程中创建的连接和游标成为可能(如flask),但存在冲突和损坏数据/条目的风险。
根据我的理解(关于我的设置flask-〉waiter-〉nginx),除非显式设置为多线程/多处理模式,否则flask将从头到尾处理每个请求,然后继续下一个请求,从而使上述危险变得无关紧要。
我设置了一个基本测试来看看我的理论是否成立。每次请求一个页面时,我都会插入一个递增的数字。然后我在PC、笔记本电脑和移动设备上垃圾刷新。结果164个条目被手动检查完整性并通过。
最后:请记住,我可能遗漏了一些东西,我的方法不是压力测试,也不是我们设置之间的差异。
希望这有帮助!
我建议的第一种方法不能在 flask 中复制。我怀疑这是由于 flask 线程活动。

相关问题