【问题标题】:Optimizing reading very large csv and writing it to SQLite优化读取非常大的 csv 并将其写入 SQLite
【发布时间】:2018-10-25 01:28:25
【问题描述】:

我有一个 10gb 的用户 ID 和性别的 csv 文件,这些文件有时会重复。

userID,gender
372,f
37261,m
23,m
4725,f
...

这是我导入 csv 并将其写入 SQLite 数据库的代码:

import sqlite3
import csv


path = 'genders.csv'
user_table = 'Users'

conn = sqlite3.connect('db.sqlite')
cur = conn.cursor()

cur.execute(f'''DROP TABLE IF EXISTS {user_table}''')

cur.execute(f'''CREATE TABLE {user_table} (
            userID INTEGER NOT NULL, 
            gender INTEGER,
            PRIMARY KEY (userID))''')

with open(path) as csvfile:
    datareader = csv.reader(csvfile)
    # skip header        
    next(datareader, None)
    for counter, line in enumerate(datareader):
        # change gender string to integer
        line[1] = 1 if line[1] == 'f' else 0

        cur.execute(f'''INSERT OR IGNORE INTO {user_table} (userID, gender) 
                    VALUES ({int(line[0])}, {int(line[1])})''')

conn.commit()
conn.close()

目前,处理 1MB 文件需要 10 秒(实际上,我有更多的列,也创建了更多的表。)。 我不认为 pd.to_sql 可以使用,因为我想要一个主键。

【问题讨论】:

    标签: python sqlite csv bigdata


    【解决方案1】:

    不要对每一行使用cursor.execute,而是使用cursor.executemany并一次插入所有数据。

    _list=[(a,b,c..),(a2,b2,c2...),(a3,b3,c3...)......] 格式存储您的值

    cursor.executemany('''INSERT OR IGNORE INTO {user_table} (userID, gender,...) 
                        VALUES (?,?,...)''',(_list))
    conn.commit()
    

    信息:

    https://docs.python.org/2/library/sqlite3.html#module-sqlite3

    【讨论】:

    • 这个列表不会比我的内存大吗?
    • 你可以使用计数器分解列表,然后执行多次执行
    • 谢谢。它的运行速度仍然比 pd.to_sql 慢 5 倍以上。
    • 正确的做法是为executemany() 提供一个迭代器,该迭代器从CSV 动态读取和转换数据。
    • 你能提出一个更详细的答案吗?谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多