使用 python 在 sqlite3 数据库中存储大量 API 数据的最有效方法

Posted

技术标签:

【中文标题】使用 python 在 sqlite3 数据库中存储大量 API 数据的最有效方法【英文标题】:Most efficient way to store large amount of API data in an sqlite3 database using python 【发布时间】:2021-08-19 23:38:57 【问题描述】:

我正在使用 requests 访问 HTTP REST API。 API 返回我想要解析然后提交到 sqlite3 数据库的 JSON。一个 JSON 响应可能大致如下所示:


    entry1: 
        
            key1:value1, 
            key2:value2
        , 
    entry2:
        
            key2:value2
        

另一个可能如下所示:


    entry3: 
        
            key1:value1, 
            key2:value2,
            key3:value3
        , 

我想将其保存到如下表格中:

+--------+--------+--------+--------+
| entry  | key1   | key2   | key3   |
+--------+--------+--------+--------+
| entry1 | value1 | value2 | NULL   |
+--------+--------+--------+--------+
| entry2 | NULL   | value2 | NULL   |
+--------+--------+--------+--------+
| entry3 | value1 | value2 | value3 |
+--------+--------+--------+--------+

实际上,我正在循环访问数以千计的条目。我的问题如下:

我不知道所有可能出现的键 key1key2key3 ... key_n,因为 API 没有记录这一点。对我来说,对整个数据集进行一次循环只是为了弄清楚在向 API 的每个请求收费时可能可能出现哪些列也太昂贵了。

有一个明显的解决方案,即检查当前请求的所有条目的列是否存在于我的表中,并根据需要向表中添加列。

我的问题有两个:

我应该在pandas.DataFrame 的python 代码中执行上述检查,还是应该使用SQL 命令直接提交到我的sqlite3 数据库,从而绕过在运行时将DataFrame 存储在我的RAM 中的需要?在sqlite3 中添加这样的列(即使用ALTER TABLE 语句)是不好的做法吗? 我是否忽略了解决此问题的其他(可能更好的)方法?

【问题讨论】:

你看过“JSON1”扩展sqlite.org/json1.html @JonSG 谢谢,但是在处理和操作 JSON 方面,python 更加通用 【参考方案1】:

SQlite3 不允许对表进行完整 更改。它允许重命名表,添加和删除列(这听起来像是您需要的),仅此而已。 More info on that here.

但是,对于您要导入的内容,听起来您需要一个非关系数据库。您是否考虑过使用 MongoDB 之类的东西?它允许您将任何对象放入数据库并根据您需要的数据调用它。

假设这不是一个选项,我相信你最好的选择是使用 python 到query your SQlite3 table info 并使用那里的结果添加一个列,如果需要的话,无论是每个项目(这将是昂贵的)或所有项目在一次。您可以一次对所有项目执行此操作,方法是向您的 API 发送一个大的覆盖所有查询,然后将返回值存储在一个 txt 文件中,然后解析该文件以适应表并存储数据。

【讨论】:

我只需要添加列,这样就足够了。 MongoDB 听起来很酷,但我认为这对于这个特定项目来说有点过头了。没有大型的全面查询。这是一个商业 API,它的设计方式是要求用户根据他们需要的确切数据(哪个“条目”)提出请求...... 那么按照书面规定,如果需要,请求后跟创建列是您的最佳选择。【参考方案2】:

只需将您的 API 信息存储在一个临时表 features 中,其中包含三列 idftypefeature。滚动后,基于SELECT DISTINCT ftype FROM features 创建最终表representations 并执行类似的操作

cur.executemany("INSERT INTO representations(id,?) VALUES(?,?)",((ftype,ID,feat,) for ID,ftype,field in rows));

同时使用另一个光标滚动features 以获取rows

警告:我没有对此进行测试。

根据@LaytonGB 的建议,您也可以为此使用文本文件。

【讨论】:

以上是关于使用 python 在 sqlite3 数据库中存储大量 API 数据的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 sqlite3 在磁盘上保存数据库 - Python [重复]

python-简单的sqlite3使用

python内置的sqlite3模块,使用其内置数据库

Python 之 Sqlite3数据库

Python 之 Sqlite3数据库

使用 Python 将 CSV 文件导入 sqlite3 数据库表