首先,這是我第一個使用SQLAlchemy的項目,所以我還是比較新的。選擇SQLAlchemy中的主鍵對象列表
我正在製作一個使用GTFS數據的系統。我有一個後端似乎能夠非常有效地查詢數據。
我想要做的是允許GTFS文件用新數據更新數據庫。我碰到的問題非常明顯,如果我試圖插入的數據已經在數據庫中,那麼我們在主鍵的唯一性上存在衝突。
出於效率的原因,我決定使用下面的代碼來進行插入,其中model是我想要插入數據的模型對象,data是預先計算並清除的要插入的字典列表。
for chunk in [data[i:i+chunk_size] for i in xrange(0, len(data), chunk_size)]:
engine.execute(model.__table__.insert(),chunk)
想到兩種解決方案。
我找到了一種方法來做插入,這樣如果有碰撞,我們不關心,也不會失敗。我相信上面的代碼使用的是TableClause,所以我先在那裏查了一下,希望找到一個合適的替代品或標誌,但沒有運氣。
在我們執行數據清理之前,我們得到主鍵值列表,如果給定元素與主鍵匹配,我們跳過清理並插入值。我發現我能從Table.primary_key獲得PrimaryKeyConstraint,但我似乎無法獲取Columns,或者找到一種方法來只查詢特定列(在我的情況下是主鍵)。
如果我能找到辦法做到這一點,就應該足夠了。
在過去的幾個小時裏對這兩個問題進行了研究之後,我似乎無法找到任何一個。我希望以前有人可能會這樣做,並指出我的方向是正確的。
在此先感謝您的幫助!
更新1:有第三個選項我沒有提到上面。那就是清除數據庫中的所有數據,並重新插入它。我不希望這樣做,因爲即使使用小型GTFS文件,也容易插入數十萬個元素,而這似乎需要大約半小時的時間才能完成,這意味着如果這樣做會導致生產中出現大量宕機進行更新。
哇,它的工作原理,但它肯定需要一個性能損失,不是嗎?到目前爲止,我似乎看到基於相同尺寸的2倍性能命中。 –
這是因爲會話可能需要檢查*每個*合併對象,如果數據庫已經有一行它。如果你知道該行已經存在,則在'merge()'調用中加入'load = False'來防止發生這種檢查。 –
另外,請注意,如果會話已經知道給定的主鍵,則不必再次檢查數據庫。對所有當前對象的查詢會給會話提供這些知識,這可能會顯着加速插入。 –