2017-02-22 96 views
0

我有一個使用Scrapy的網絡抓取工具,它使用Deferreds構建在Twisted上。對於我要插入到PostgreSQL數據庫中的多個不同表中的每個頁面。我想這個插入是非阻塞的。有沒有辦法讓非阻塞Postgres與SQLAlchemy等ORM交互?非阻塞PostgreSQL ORM

我知道有非阻塞Postgres與alchimiatxpostgres交互,但都不提供ORM功能。如果答案是不可能的,我會使用其中的一個。其中一個比另一個更受歡迎嗎?

回答

1

ORM在Python中構建的方式通常不適合異步操作。

似乎很有吸引力的Python ORM的主要特性顯然是獲取和設置值的正常屬性訪問。然而,這兩個現在的問題。

對於屬性訪問異步操作,明顯的行爲是爲database_object.some_field這樣的東西評估爲Deferred。然後,應用程序將等待此接收實際值。代碼最終看起來像這樣:

d = database_object.some_field 
def got_some_field(result): 
    print("DB obj some_field = {}".format(result)) 
d.addCallback(got_some_field) 

而不是一個簡單的表達式,你有四行代碼。人們可以爭辯說,這完全破壞了ORM的價值。它可能可能通過預加載數據庫中的值來解決此問題。但是,預先加載所有內容並不總是可取的(它可能會損害性能),但並不總是顯而易見的,這樣做是正確的(如果啓動事務,預加載某些值,執行可能會更改這些值的操作,則從Python對象中檢索它們,會發生什麼?)。

更新值更糟糕。而一個同步ORM可能會讓你:

database_object.some_field = 3 

異步ORM將如何工作的東西類似?分配無法產生任何值。所以你需要另一個不方便的模式來正確地更新。喜歡的東西:

d = database_object.update("some_field", 3) 
def updated(ignored): 
    # Continue ... 
d.addCallback(updated) 

還是一個非常複雜的系統,要做到這一點的方式,不允許在Python的存儲在數據庫中的值和不一致的幕後。這可能並非不可能,但所涉及的複雜程度可能是爲什麼沒有人似乎已經解決了這個問題。

+0

謝謝;這非常有趣。 [這個twistar教程](http://findingscience.com/twistar/)似乎表明他們已經開發了一些方法來解決這個問題。這是如何適應你已經佈置的框架? – Hatshepsut

+0

我認爲twistar比ORM稍低一些 - 它是一種「活動記錄模式」實現,對於構建ORM非常有用,但它缺少大多數人會認爲是ORM的一部分。例如,您不需要具有基於屬性訪問的數據訪問 - 您可以使用顯式(單對象)「保存」方法來獲取和設置方法。它接受了Python對象和數據庫在一段時間內不一致的觀點(直到你保存了更改)。因此,應用程序必須小心,不要驚訝於不反映未保存更改的查詢結果。 –

+0

(但用一粒鹽 - 我最後一次真正的看twistar大概是半年前)。 –