3

我对 python 很陌生,一直在研究我的树莓派来启动并运行一个脚本,以将数百万个传感器数据记录导入 sqlite。我想在交易中这样做,以提高流程效率。我正在尝试将事务分解为 10k 块,如下所示:Python CSV to SQLite

到目前为止我有

import csv, sqlite3, time

def chunks(data, rows=10000):
    for i in range (0, len(data), rows):
            yield data[i:i+rows]

if __name__ == "__main__":

    t = time.time()

con = sqlite3.connect('test.db')
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS sensor;")
cur.execute("CREATE TABLE sensor(key INT, reading REAL);")

filename = 'dummy.csv'
reader = csv.reader(open(filename,"r"))
divdata = chunks(reader)

for chunk in divdata:
    cur.execute('BEGIN TRANSACTION')

    for col1, col2 in chunk:
            cur.execute('INSERT INTO sensor (key, reading) VALUES (?, ?)', (col1, col2))

    con.execute('COMMIT')

我在 python 3.2.3 中收到以下错误:

Traceback (most recent call last):
File "/home/pi/test1.py", line 20, in <module>
for chunk in divdata:
File "/home/pi/test1.py", line 4, in chunks
for i in range (0, len(data), rows):
TypeError: object of type '_csv.reader' has no len()

我显然在某处搞砸了块部分,因为没有块和事务,一切(基本插入)都可以正常工作。任何帮助表示赞赏。

4

3 回答 3

3

您的 SQL 看起来不错。不过,我确实看到您的 CSV 阅读器存在问题:它不支持len()您在chunks().

如果您需要将文件分成块,您可以使用更典型的for row in data循环,或者使用此线程中描述的技术之一。

于 2013-08-05T16:38:08.143 回答
1

任务中的代码片段有两个问题:

  1. 调用中的读者chunks应该被包裹在list()
  2. “提交”应该一直在使用连接的commit()方法

查看固定代码:

import csv, sqlite3, time

def chunks(data, rows=10000):
    for i in range (0, len(data), rows):
            yield data[i:i+rows]

if __name__ == "__main__":

    t = time.time()

con = sqlite3.connect('test.db')
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS sensor;")
cur.execute("CREATE TABLE sensor(key INT, reading REAL);")

filename = 'dummy.csv'
reader = csv.reader(open(filename,"r"))
divdata = chunks(list(reader))

for chunk in divdata:
    cur.execute('BEGIN TRANSACTION')

    for col1, col2 in chunk:
            cur.execute('INSERT INTO sensor (key, reading) VALUES (?, ?)', (col1, col2))

    con.commit()
于 2014-11-16T11:04:49.690 回答
1

问题是您从该csv.reader方法获得的对象不支持该len()功能。事实上,这个 CSV 阅读器只有在收到指示时才会读取,因此它不知道文件中有多少记录。

因此,您需要更新chunks方法以处理不知道要分块的事物的数量。用这个替换那个函数:

def chunks(data, n=10000):
    buffer = [None] * n
    idx = 0
    for record in data:
        buffer[idx] = record
        idx += 1
        if idx == n:
            yield buffer
            buffer = [None] * n
            idx = 0
    if idx > 0:
        yield buffer[:idx]

它的作用是:只要有要检索的记录,它就会不断从您的文件中检索记录,并且每一n行都会发出一个n记录列表。例如:

>>> for c in chunks(range(10), 3):
...     print(c)
...
[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[9]
于 2015-08-28T12:58:30.940 回答