【问题标题】:python sqlite3 executemany using multiple listspython sqlite3 executemany使用多个列表
【发布时间】:2016-01-06 12:18:17
【问题描述】:

背景:
所以我有一个大数组,我从一个来源读取并尝试使用 python(有效地)写入 SQLite3。

目前我使用默认形式:

cursor.executemany("INSERT into mytable1 VALUES(?,?,?)", my_arr.tolist())

现在我想扩展到几十万张表。我希望能够做以下事情(希望):

cursor.executemany("INSERT into ? VALUES(?,?,?)", TableNameList, my_arr.tolist())

问题:

  • 有没有办法在不向数组中插入列的情况下做到这一点 在将其转换为列表之前?什么?
  • 如果没有这样的方法,那么建议和替代方案是 请求。

我尝试在 stackexchange 中查找,但可能遗漏了一些内容。
我尝试查看 Python SQLite 文档,但没有看到类似的内容。 我尝试了通用的谷歌搜索。

【问题讨论】:

  • my_arr的类型是什么?
  • 我正在使用 np.empty((row_size,col_size), dtype=object)
  • “现在我想扩展到几十万张表” 为什么?那不是标准化的。改为添加一列;在您将插入mytable1 的位置,将1 插入新列。
  • 当前列很大,占据了大部分空间。如果我将表拆分为该列上的唯一表,那么我会得到几十万个表(行数相对较小),这些表按对摘要视图计算有用的值进行分组,并且我们会得到一大块改进的足迹。
  • 您是将相同的my_arr 值(多行)插入到每个表中,还是将my_arr 的每一行插入到不同的表中?也就是说,TableNameList 和 my_arr 之间的映射是什么?

标签: python sql numpy sqlite executemany


【解决方案1】:

首先,Python 位。假设my_arr 是某种二维数组,而.tolist() 产生一个列表列表,是的,有一种方法可以向列表中的每一行添加一个元素:

result = [[a]+b for a,b in zip(TableNameList, my_arr.tolist()]

其次,SQL 位。不,您不能使用? 指定表名。表名必须逐字出现在 SQL 语句中。我能为您提供的最好的方法是多次运行curssor.execute

for table, values in zip(TableNameList, my_arr):
    c.execute("INSERT INTO %s VALUES (?, ?, ?)"%table, values)

但是,请注意您是否信任TableNameList 的来源。在%s 中使用不受信任的数据会导致 SQL 注入安全漏洞。

示例程序:

import sqlite3
import numpy as np
import itertools

my_arr = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
TableNameList = 't1', 't1', 't2', 't3'

conn = sqlite3.connect(':memory:')
c = conn.cursor()

c.execute('''CREATE TABLE t1 (c1, c2, c3)''')
c.execute('''CREATE TABLE t2 (c1, c2, c3)''')
c.execute('''CREATE TABLE t3 (c1, c2, c3)''')

## Insert a row of data
#c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)")

for table, values in itertools.izip(TableNameList, my_arr):
    c.execute("INSERT INTO %s VALUES (?, ?, ?)"%table, values)

# Save (commit) the changes
conn.commit()

# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
conn.close()

【讨论】:

  • 从 ~100 行/秒到 ~4000 行/秒的大幅加速来自于经过良好调整的 executemany。失去那将是一个问题。
  • 您可以在每张桌子上尝试一个 executemany。假设TableNameList 看起来像['table1', 'table1', 'table2', 'table3', 'table1'](即my_arr 的每行一个条目),并且TableNameList 中有重复值,那么对每个表的数据进行分组并在每个表中运行一个executemany() 可能会有所帮助.
猜你喜欢
  • 2017-10-02
  • 1970-01-01
  • 2019-01-30
  • 2016-02-21
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 2012-05-19
  • 1970-01-01
相关资源
最近更新 更多