【发布时间】:2018-02-28 22:32:36
【问题描述】:
现有数据库和预期结果:
我有一个更大的 SQLite 数据库(12gb,超过 4400 万行的表),我想在 Python3 中使用 Pandas 对其进行修改。
示例目标:我希望将这些大表之一(4400 万行)分块读入 DF,操作 DF 块,并将结果写入新表。如果可能的话,如果新表存在,我想替换它,并将每个块附加到它。
因为我的操作只添加或修改列,新表的行数应该与原始表相同。
问题:
主要问题似乎源于以下代码中的以下行:
df.to_sql(new_table, con=db, if_exists = "append", index=False)
- 当在下面的代码中运行这一行时,我似乎一直得到一个额外的 size=N 块,加上一个比我预期的观察结果。
- 此代码第一次使用新表名运行时出现错误:
Traceback (most recent call last):
File "example.py", line 23, in <module>
for df in df_generator:
File "/usr/local/lib/python3.5/site-packages/pandas/io/sql.py", line 1420, in _query_iterator
data = cursor.fetchmany(chunksize)
sqlite3.OperationalError: SQL logic error or missing database
如果我随后使用相同的新表名重新运行脚本,它将针对每个块运行,并为额外的块运行 +1 行。
当
df.to_sql()行被注释掉时,循环运行预期的块数。
完整代码的问题测试示例:
完整代码:example.py
import pandas as pd
import sqlite3
#Helper Functions Used in Example
def ren(invar, outvar, df):
df.rename(columns={invar:outvar}, inplace=True)
return(df)
def count_result(c, table):
([print("[*] total: {:,} rows in {} table"
.format(r[0], table))
for r in c.execute("SELECT COUNT(*) FROM {};".format(table))])
#Connect to Data
db = sqlite3.connect("test.db")
c = db.cursor()
new_table = "new_table"
#Load Data in Chunks
df_generator = pd.read_sql_query("select * from test_table limit 10000;", con=db, chunksize = 5000)
for df in df_generator:
#Functions to modify data, example
df = ren("name", "renamed_name", df)
print(df.shape)
df.to_sql(new_table, con=db, if_exists = "append", index=False)
#Count if new table is created
try:
count_result(c, new_table)
except:
pass
1.结果当
#df.to_sql(new_table, con=db, if_exists = "append", index=False)(问题行已注释掉):
$ python3 example.py
(5000, 22)
(5000, 22)
这是我所期望的,因为示例代码将我的大表限制为 10k 行。
2。结果当
df.to_sql(new_table, con=db, if_exists = "append", index=False)一个。问题行没有被注释掉
b.这是第一次使用 new_table 运行代码:
$ python3 example.py
(5000, 22)
Traceback (most recent call last):
File "example.py", line 23, in <module>
for df in df_generator:
File "/usr/local/lib/python3.5/site-packages/pandas/io/sql.py", line 1420, in _query_iterator
data = cursor.fetchmany(chunksize)
sqlite3.OperationalError: SQL logic error or missing database
3.结果当
df.to_sql(new_table, con=db, if_exists = "append", index=False)一个。问题行没有被注释掉
b.上面的代码使用 new_table 运行 第二次:
$ python3 example.py
(5000, 22)
(5000, 22)
(5000, 22)
(1, 22)
[*] total: 20,001 rows in new_table table
因此,我首先遇到的问题是第一次运行时代码中断(结果 2),其次,第二次运行时的总行数(结果 3)是我预期的两倍以上。
任何关于如何解决此问题的建议将不胜感激。
【问题讨论】:
-
您只是想重命名 SQLite 表中的列吗?
-
@MaxU 不,重命名功能只是一个示例修改。我想跨多个列执行一些复杂的操作,这些操作在 Pandas 中比在 SQL 中更容易。
-
试试这个:
db = sqlite3.connect("test.db", isolation_level=None) -
@MaxU,太好了,第一次工作并产生了预期的结果!我确实注意到,虽然初始(失败的代码)几乎会在第二次尝试时立即运行,但使用您的解决方案,代码几乎就像每个块都有一个
time.sleep(8)一样存在滞后。有没有办法加快速度,或者我应该在我机器上的内存允许的情况下增加块大小?
标签: python pandas sqlite pandas-to-sql