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

問題は、メソッドから取得したオブジェクトが関数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 に答える