SQLite transaction for CSV importing

前端 未结 3 1578
眼角桃花
眼角桃花 2020-12-19 21:56

I\'m very new to python and have been working on my raspberry pi to get a script up and running to import millions of sensor data records into sqlite. I want to do this in t

相关标签:
3条回答
  • 2020-12-19 22:24

    Your SQL looks okay. I do see a problem with your CSV reader, though: it doesn't support len() the way you're using it in chunks().

    You could either use the more typical for row in data loop, or use one of the techniques described in this thread if you need to break the file into chunks.

    0 讨论(0)
  • 2020-12-19 22:39

    The problem is that the object you get from the csv.reader method does not support the len() function. In fact, this CSV reader reads only when instructed to do so, and as such, it does not know how many records are in the file.

    As such, you need to update the chunks method to deal with not knowing the amount of things to be chunked. Replace that function with this:

    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]
    

    What this does is: it keeps retrieving records from your file as long as there are records to retrieve, and every n rows, emits a list of n records. For example:

    >>> for c in chunks(range(10), 3):
    ...     print(c)
    ...
    [0, 1, 2]
    [3, 4, 5]
    [6, 7, 8]
    [9]
    
    0 讨论(0)
  • 2020-12-19 22:46

    There were two problems in the code snippet in the quest:

    1. the reader in the call to chunks should have been wrapped in list()
    2. the 'commit' should have been using the connection's commit() method

    See the fixed code:

    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()
    
    0 讨论(0)
提交回复
热议问题