我想避免使用Python的fetchall
方法将查询结果插入到新的SQLite表中,因为我遇到了使用fetchone
或fetchmany
可能会避免的内存问题。但是,当我尝试使用游标循环查询时,插入仅在一次传递中发生(在这种情况下,仅插入预定义的1000行而不是全部)。但是,将循环结果附加到空列表会导致所有行都被追加,因此它不是循环本身就是问题。
以下脚本不起作用:
def fetchsome(cursor, some=1000):
fetch = cursor.fetchmany
while True:
rows = fetch(some)
if not rows: break
for row in rows:
cursor.execute("insert into zip4_upd values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", row)
conn.commit()
cur = conn.cursor()
cur.execute("""select * from zip4 left outer join alias on zip4.primarykey = alias.primarykey left outer join detail on zip4.citystatekey = detail.detail_citystatekey""")
fetchsome(cur)
答案 0 :(得分:3)
这听起来像是executemany
cursor.executemany('''insert into zip4_upd values(
?,?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?,?,?,?,?,?,?)''', row_gen(cursor))
相反,让row_gen
成为每行yields
的生成器。这是懒惰的,应该是内存效率。
我的代码有点朦胧,但这样的事情应该是你的row_gen
def row_gen(cursor, some=1000):
fetch = cursor.fetchmany
while True:
rows = fetch(some)
if not rows: break
for row in rows:
yield row
假设我正确理解了代码,您需要在row_gen
调用中正确调用executemany
,因此它以... row_gen(cursor)