【问题标题】:Fast data moving from CSV to SQLite by Python通过 Python 将数据从 CSV 快速移动到 SQLite
【发布时间】:2015-03-09 18:39:31
【问题描述】:

我有问题。大约有数百个 CSV 文件。每一行有 1,000,000 行。 我需要以特定方式移动该数据,但脚本运行速度非常慢(每小时通过几十万)。

我的代码:

    import sqlite3 as lite
    import csv
    import os



my_file = open('file.csv', 'r')
reader = csv.reader(my_file, delimiter=',')


date = '2014-09-29'

con = lite.connect('test.db', isolation_level = 'exclusive')
for row in reader:

    position = row[0]
    item_name = row[1]



    cur = con.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS [%s] (Date TEXT, Position INT)" % item_name)
    cur.execute("INSERT INTO [%s] VALUES(?, ?)" % item_name, (date, position))
con.commit()

我找到了一个关于isolation_level和single access to database的信息,但是效果不好。

行 CSV 文件具有以下结构:1,item1 | 2、项目2

有人可以帮助我吗?谢谢!

【问题讨论】:

    标签: python sqlite csv


    【解决方案1】:

    不要做 sql 插入。先准备CSV文件,然后做:

    .separator <separator>
    .import <loadFile> <tableName>
    

    请看这里:http://cs.stanford.edu/people/widom/cs145/sqlite/SQLiteLoad.html

    【讨论】:

    • 这如何创建 OP 想要的动态表名?
    • @fukanchik 给出结构非常重要:表名:item1 |项目2 |表中的 item3 行:2014-03-15, 1 | 2014-03-16, 121
    • 使用适合 .import 的结构创建临时文件。从您的 CSV 复制数据,运行导入。
    【解决方案2】:

    您当然不想为要插入的每一行创建一个新的游标对象 - 在每一行检查表创建肯定会减慢您的速度 -

    我建议分两次执行此操作:首先 您创建所需的表,在您记录的第二遍 数据。如果它仍然很慢,你可以做一个 更复杂的内存数据集合 插入并执行“executemany”-但这会 需要一些复杂性才能在内存中按名称对数据进行分组 在提交之前;。

    import sqlite3 as lite
    import csv
    import os
    
    my_file = open('file.csv', 'r')
    reader = csv.reader(my_file, delimiter=',')
    
    date = '2014-09-29'
    
    con = lite.connect('test.db', isolation_level = 'exclusive')
    cur  = con.cursor()
    
    table_names = set(row[1] for row in reader)
    my_file.seek(0)
    
    for name in table_names:
         cur.execute("CREATE TABLE IF NOT EXISTS [%s] (Date TEXT, Position INT)" % item_name)
    
    for row in reader:
    
        position = row[0]
        item_name = row[1]
    
        cur.execute("INSERT INTO [%s] VALUES(?, ?)" % item_name, (date, position))
    
    con.commit()
    

    【讨论】:

      【解决方案3】:

      代码效率低,因为它为 CSV 中的每一行执行两个 SQL 语句。尝试优化。

      1. 有没有办法先处理 CSV 并将其转换为 SQL 语句?
      2. CSV 中的行是否按表(item name's)分组?如果是,您可以累积要插入到同一个表中的行(为同一个表生成一组INSERT 语句),并且只在结果组的语句前加上一次CREATE TABLE IF NOT EXISTS,而不是每个语句。李>
      3. 如果可能,请使用批量插入。如果我做对了,SQLite v.3.27.1 引入了批量插入。更多信息:Is it possible to insert multiple rows at a time in an SQLite database?
      4. 如果需要,以块的形式批量插入。更多信息:Bulk insert huge data into SQLite using Python

      【讨论】:

        【解决方案4】:

        我也有同样的问题。现在解决了!把方法分享给遇到同样问题的大家!

        我们以 sqlite3 数据库为例,其他数据库也可以,但不确定。我们在 python 中采用 pandas 和 sqlites 模块。

        这可以快速将 csv 文件列表 [file1,file2,...] 转换为 talbes [table1,table2,...]。

        import pandas as pd
        import sqlite3 as sql
        
        
        DataBasePath="C:\\Users\\...\\database.sqlite"
        conn=sql.connect(DataBasePath)
        
        filePath="C:\\Users\\...\\filefolder\\"    
        datafiles=["file1","file2","file3",...]
        
        for f in datafiles:
            df=pd.read_csv(filePath+f+".csv")        
            df.to_sql(name=f,con=conn,if_exists='append', index=False)    
        conn.close()
        

        更重要的是,如果数据库不存在,此代码可以创建数据库。 pd.to_sql() 'if_exists' 的参数很重要。默认值为“fail”,如果存在则导入数据,否则什么也不做;如果表存在,“replace”将首先删除表,然后创建新表并导入数据; "append" 如果存在则导入数据,否则创建一个新的可以导入数据。

        【讨论】:

          猜你喜欢
          • 2018-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-28
          • 2019-01-07
          • 1970-01-01
          • 2019-02-26
          相关资源
          最近更新 更多