gpt4 book ai didi

python - SQLAlchemy 使用生成器执行许多

转载 作者:太空宇宙 更新时间:2023-11-03 12:07:07 24 4
gpt4 key购买 nike

问题:对于连接对象的执行函数,是否可以使用返回字典而不是字典列表的生成器来执行“executemany”插入?

详细信息:我正在尝试通过 core expressions 学习 SQLAlchemy .作为测试,我有一个相当大的数据集,通过迭代器从文件访问,我试图将其传输到 PostgreSQL 表中,但插入单个行的速度非常慢(请参见下面的示例 1)。根据documentation , 连接对象的 execute()函数将执行相当于 executemany() 的操作如果传入字典列表而不是单个字典。我做了一些快速测试,确实这种方法对于插入组要快得多。不幸的是,对于我的大数据集,我无法在内存中创建完整的字典列表,因此我的问题...

示例 1:以下(伪)代码对于大量数据非常慢

from sqlalchemy import MetaData, Table, Column

metadata = MetaData()
data = Table('data', metadata, Column...)

engine = sql.create_engine('postgresql://user:pass$@localhost/testdb')
metadata.create_all(engine)

conn = engine.connect()
ins = data.insert()
for datum in large_data_iterator:
datum_dict = do_some_proc(datum)
conn.execute(ins, datum_dict)

因为 execute 可以取多个值,所以最好替换最后的 for使用以下生成器版本循环:

def datagen(iterator):
for datum in large_data_iterator:
datum_dict = do_some_proc(datum)
yield datum_dict

conn = engine.connect()
ins = data.insert()
conn.execute(ins, datagen(large_data_iterator))

但是,这会引发以下异常:AttributeError:'list' object has no attribute 'keys'。

有谁知道生成器版本是否可以正常工作?或者更好的方法来做到这一点也很棒。谢谢!

注意:我测试了一个修改过的生成器表达式,它以字典列表的形式生成 block (如下),它比单独执行更快。但是,我不知道如何选择最佳的 block 数,而且我担心生成器代码的复杂性会使其更容易出错。 (但如果这是唯一的方法......)

def datagen(iterator):
output = []
N = 0
for datum in large_data_iterator:
datum_dict = do_some_proc(datum)
output.append(datum_dict)
N += 1
if N == 100: # or whatever
yield output
N = 0
output = []
if output != []:
yield output

最佳答案

execution_options对于 Connection,它采用 stream_results 参数,但不幸的是在底部它说“该标志当前仅被 psycopg2 方言理解”,即使还有其他支持流式传输的驱动程序(例如 oursql)。

在sqlalchemy完全支持之前,可以很方便的写一个辅助函数给break any iterable into chunks以避免修改生成器的错误倾向。

关于python - SQLAlchemy 使用生成器执行许多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27098000/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com