pandas.DataFrame.to_sql 的进度条
Progress bar for pandas.DataFrame.to_sql
我想将数据从大型 csv 文件迁移到 sqlite3 数据库。
我在 Python 3.5 上的代码使用 pandas:
con = sqlite3.connect(DB_FILENAME)
df = pd.read_csv(MLS_FULLPATH)
df.to_sql(con=con, name="MLS", if_exists="replace", index=False)
是否可以打印to_sql方法执行的当前状态(进度条)?
我看了关于 tqdm 的文章,但没有找到如何做到这一点。
不幸的是 DataFrame.to_sql
不提供逐块回调,tqdm 需要它来更新其状态。但是,您可以逐块处理数据帧:
import sqlite3
import pandas as pd
from tqdm import tqdm
DB_FILENAME='/tmp/test.sqlite'
def chunker(seq, size):
# from
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
def insert_with_progress(df, dbfile):
con = sqlite3.connect(dbfile)
chunksize = int(len(df) / 10) # 10%
with tqdm(total=len(df)) as pbar:
for i, cdf in enumerate(chunker(df, chunksize)):
replace = "replace" if i == 0 else "append"
cdf.to_sql(con=con, name="MLS", if_exists=replace, index=False)
pbar.update(chunksize)
df = pd.DataFrame({'a': range(0,100000)})
insert_with_progress(df, DB_FILENAME)
请注意,我在这里生成内联 DataFrame 是为了获得一个没有依赖性的完整可行示例。
结果相当惊人:
我想分享 miraculixx 发布的解决方案的变体 - 我必须为 SQLAlchemy 进行更改:
#these need to be customized - myDataFrame, myDBEngine, myDBTable
df=myDataFrame
def chunker(seq, size):
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
def insert_with_progress(df):
con = myDBEngine.connect()
chunksize = int(len(df) / 10)
with tqdm(total=len(df)) as pbar:
for i, cdf in enumerate(chunker(df, chunksize)):
replace = "replace" if i == 0 else "append"
cdf.to_sql(name="myDBTable", con=conn, if_exists="append", index=False)
pbar.update(chunksize)
tqdm._instances.clear()
insert_with_progress(df)
用户 miraculixx 在上面有一个很好的例子,谢谢你。但是如果你想将它用于各种大小的文件,你应该添加如下内容:
chunksize = int(len(df) / 10)
if chunksize == 0:
df.to_sql(con=con, name="MLS", if_exists="replace", index=False)
else:
with tqdm(total=len(df)) as pbar:
...
我想将数据从大型 csv 文件迁移到 sqlite3 数据库。
我在 Python 3.5 上的代码使用 pandas:
con = sqlite3.connect(DB_FILENAME)
df = pd.read_csv(MLS_FULLPATH)
df.to_sql(con=con, name="MLS", if_exists="replace", index=False)
是否可以打印to_sql方法执行的当前状态(进度条)?
我看了关于 tqdm 的文章,但没有找到如何做到这一点。
不幸的是 DataFrame.to_sql
不提供逐块回调,tqdm 需要它来更新其状态。但是,您可以逐块处理数据帧:
import sqlite3
import pandas as pd
from tqdm import tqdm
DB_FILENAME='/tmp/test.sqlite'
def chunker(seq, size):
# from
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
def insert_with_progress(df, dbfile):
con = sqlite3.connect(dbfile)
chunksize = int(len(df) / 10) # 10%
with tqdm(total=len(df)) as pbar:
for i, cdf in enumerate(chunker(df, chunksize)):
replace = "replace" if i == 0 else "append"
cdf.to_sql(con=con, name="MLS", if_exists=replace, index=False)
pbar.update(chunksize)
df = pd.DataFrame({'a': range(0,100000)})
insert_with_progress(df, DB_FILENAME)
请注意,我在这里生成内联 DataFrame 是为了获得一个没有依赖性的完整可行示例。
结果相当惊人:
我想分享 miraculixx 发布的解决方案的变体 - 我必须为 SQLAlchemy 进行更改:
#these need to be customized - myDataFrame, myDBEngine, myDBTable
df=myDataFrame
def chunker(seq, size):
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
def insert_with_progress(df):
con = myDBEngine.connect()
chunksize = int(len(df) / 10)
with tqdm(total=len(df)) as pbar:
for i, cdf in enumerate(chunker(df, chunksize)):
replace = "replace" if i == 0 else "append"
cdf.to_sql(name="myDBTable", con=conn, if_exists="append", index=False)
pbar.update(chunksize)
tqdm._instances.clear()
insert_with_progress(df)
用户 miraculixx 在上面有一个很好的例子,谢谢你。但是如果你想将它用于各种大小的文件,你应该添加如下内容:
chunksize = int(len(df) / 10)
if chunksize == 0:
df.to_sql(con=con, name="MLS", if_exists="replace", index=False)
else:
with tqdm(total=len(df)) as pbar:
...