問題:對於一個Connnection對象的執行功能,可以使用一臺發電機返回字典而不是字典做一個「executemany」的列表中插入?SQLAlchemy的exectutemany與發電機
詳細信息:我試圖通過該core expressions努力學習SQLAlchemy的。作爲測試,我有一個相當大的數據集,從文件訪問通過一個迭代中,我試圖轉移到一個PostgreSQL表,但插入各個行是相當緩慢(參見下文實施例1)。按照documentation,如果詞典列表中傳遞,而不是一個單一的字典Connnection對象的功能將做一個executemany()
的等價物。我做了一些快速測試,實際上這種方法對插入組來說要快得多。不幸的是,我的大數據集,我不能在內存中創建詞典的完整列表,因此我的問題...
例1:以下(僞)代碼是大量數據
的速度很慢from sqlalchemy import MetaData, Table, Column
metadata = MetaData()
data = Table('data', metadata, Column...)
engine = sql.create_engine('postgresql://user:[email protected]/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)
由於執行可以擁有多個值,這將是很好,以取代最後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的:「名單」對象沒有屬性'k餘仁生。
有誰知道是否有可能讓發電機版本的工作?或者更好的方法來做到這一點也很好。謝謝!
注:我測試其產生組塊作爲字典(下圖)的列表的改性發生器表達,它比個人執行得更快。但是,我不知道如何選擇最佳數量的塊,我擔心發生器代碼增加的複雜性使其可能更容易出錯。 (但是,如果它是唯一的出路......)
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