【问题标题】:Open sqlite database from http in memory从内存中的http打开sqlite数据库
【发布时间】:2021-11-29 22:58:40
【问题描述】:

我有代码:

from io import BytesIO as Memory

import requests

def download_file_to_obj(url, file_obj):
    with requests.get(url, stream=True) as r:
        r.raise_for_status()
        for chunk in r.iter_content(chunk_size=None):
            if chunk:
                file_obj.write(chunk)


def main(source_url):
    db_in_mem = Memory()
    print('Downloading..')
    download_file_to_obj(source_url, db_in_mem)
    print('Complete!')
    with sqlite3.connect(database=db_in_mem.read()) as con:
        cursor = con.cursor()
        cursor.execute('SELECT * FROM my_table limit 10;')
        data = cursor.fetchall()
        print(data)
    del(db_in_mem)

my_table 已在源数据库中退出。 错误:

sqlite3.OperationalError:没有这样的表:my_table

如何将 sqlite 数据库从 http 加载到内存中?

【问题讨论】:

  • 问题是sqlite3希望它的数据库是一个真正的文件,或者内存数据库中的特殊:memory:。甚至备份 API 也只知道如何在它们之间进行复制,但是 AFAIK,没有一个能够使用像对象这样的 Python 文件,也不能使用内存映像。如果你想那样做,你将不得不找到一个内存文件系统。你可以看看pyfakefs。由您决定是否值得,或者使用真实文件是否更简单......
  • 谢谢。我认为不值得“建造花园”,使用真正的临时文件更容易。正如python的ZEN所说:简单胜于复杂。
  • @snakecharmerb 看起来像,但根本不是,因为没有办法执行 SQL 查询。做一个转储。

标签: python python-3.x sqlite


【解决方案1】:

强制 SQLite 数据库纯粹存在于内存中的最常见方法是使用特殊文件名 :memory: 打开数据库。换句话说,不是传递真实磁盘文件的名称,而是传递字符串:memory:。例如:

database = sqlite3.connect(":memory:")

完成后,不会打开任何磁盘文件。相反,一个新的数据库是纯粹在内存中创建的。数据库连接一关闭,数据库就不再存在。每个 :memory: 数据库都彼此不同。因此,打开两个数据库连接,每个连接的文件名为“:memory:”,将创建两个独立的内存数据库。

请注意,为了应用特殊的 :memory: 名称并创建纯内存数据库,文件名中不能有其他文本。因此,可以通过添加路径名在文件中创建基于磁盘的数据库,如下所示:./:memory:

在此处查看更多信息:https://www.sqlite.org/inmemorydb.html

【讨论】:

    【解决方案2】:

    您可以在this solution 之上构建并将数据插入到使用db = sqlite3.connect(":memory:") 创建的内存SQLite 数据库中。您应该能够从该数据库执行查询。

    【讨论】:

    • 尽量减少对另一个答案的依赖,因为它可能随时被删除,这会使这个答案变得毫无用处。
    猜你喜欢
    • 2010-09-21
    • 2011-09-27
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 1970-01-01
    • 2014-10-11
    • 2013-09-25
    相关资源
    最近更新 更多