Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python和Pandas的SQLite3在添加大量数据时会变慢_Python_Database_Pandas_Sqlite - Fatal编程技术网

使用Python和Pandas的SQLite3在添加大量数据时会变慢

使用Python和Pandas的SQLite3在添加大量数据时会变慢,python,database,pandas,sqlite,Python,Database,Pandas,Sqlite,我正在尝试使用Pandas的df.to_sql和python中的SQlite3在一个数据库中放入大约2GB的数据和大约1600万行。我的策略是将原始CSV分块成更小的数据帧,对它们执行一些操作,然后将它们放入SQL数据库 当我运行这段代码时,它的启动速度很快,但速度很快就会减慢。在大约300万行之后,它会减速到这样一个程度,因为它似乎不会在任何实际的时间内完成。这是什么原因?我能做些什么?我的代码如下: def chunk_read_CSV_to_db(database, table, file

我正在尝试使用Pandas的df.to_sql和python中的SQlite3在一个数据库中放入大约2GB的数据和大约1600万行。我的策略是将原始CSV分块成更小的数据帧,对它们执行一些操作,然后将它们放入SQL数据库

当我运行这段代码时,它的启动速度很快,但速度很快就会减慢。在大约300万行之后,它会减速到这样一个程度,因为它似乎不会在任何实际的时间内完成。这是什么原因?我能做些什么?我的代码如下:

def chunk_read_CSV_to_db(database, table, filepath, chunksize, delimiter=','):
    start = dt.datetime.now()
    conn = sqlite3.connect(database)
    index_start = 1
    j=0
    for df in pd.read_csv(filepath, chunksize=chunksize, iterator=True, encoding='utf-8', sep=delimiter):
        j+=1
        print '{} seconds: complete {} rows'.format((dt.datetime.now() -start).seconds, j*chunksize)
        df.to_sql(name=table, con=conn, flavor='sqlite', if_exists='append')
    conn.close()

db_name = 'store_data.db'
f9 = 'xrf_str_geo_ta4_1511.txt'
chunksize = 20000
chunk_read_CSV_to_db(os.path.join(fp, db_name), os.path.splitext(f9)[0], os.path.join(fp, f9), chunksize = chunksize, delimiter='\t')

我改用了sqlalchemy,从那以后时间就没有问题了。没有明显的放缓。代码如下

def chunk_read_CSV_to_db(database, table, filepath, chunksize, delimiter=',', index=False):
     start = dt.datetime.now()
     index_start = 1
     j=0
     for df in pd.read_csv(filepath, chunksize=chunksize, iterator=True, encoding='utf-8', sep=delimiter):
         j+=1
         print '{} seconds: complete {} rows'.format((dt.datetime.now() -start).seconds, j*chunksize)
         df.to_sql(table, db, flavor='sqlite', if_exists='append', index=index)

db = create_engine('sqlite:///store_data.db')
meta = MetaData(bind=db)

table_pop = Table('xrf_str_geo_ta4_1511', meta, 
    Column('TDLINX',Integer, nullable=True),
    Column('GEO_ID',Integer, nullable=True),
    Column('PERCINCL', Numeric, nullable=True)
)

chunksize = 20000
chunk_read_CSV_to_db(db,'xrf_str_geo_ta4_1511', os.path.join(fp, f9), chunksize = chunksize, delimiter='\t')        

解决方案:将
df.to_sql
参数设置为
index=False

所以我知道这个答案将不再与作者相关,但我偶然发现了它,因为我有完全相同的问题,并想分享我的答案

我试图使用append方法将~900.csv文件逐个加载到sql数据库中。加载开始得很快,但速度呈指数级下降,从未完成运行。这让我怀疑索引出现了问题(即每次我添加数据时熊猫都会以某种方式重新编制索引),因为这是我唯一能想到的解释减速的方法(内存似乎很好)

最后,我开始通过命令行使用sqlite3.index和.dbinfo方法来查看通过pandas创建的数据库,并与通过sqlite3直接比较的数据库进行比较。我发现pandas数据库在通过sqlite3处理时有1个索引,而不是0。而且,模式的大小要大得多

现在,pandas to_sql方法有一个索引参数。它说这个参数只是将dataframe索引作为列添加到数据库中(这听起来很无害)。但事实证明,它也使用该列作为数据库索引,而且如果您使用的是append方法,那么它可能每次(或其他)都会重新计算该索引。无论如何,当我将index参数设置为False时,.dbinfo在生成的数据帧中显示0个索引,我的问题消失了-所有数据都在很短的时间内处理完毕

因此,解决办法是:

df.to_sql(name=table, con=conn, flavor='sqlite', if_exists='append', index = False)

您的表中有索引吗?最好删除索引,添加数据,然后创建索引。请参阅长话短说:设置
index=False
,您就可以开始了。好的捕获-已更新我的答案,以便提前加载解决方案。