2012-11-18 24 views
6

當我想要使用SQLAlchemy在這樣的方式:SQLAlchemy的:返回現有的對象,而不是創建一個新的調用構造函數

email1 = EmailModel(email="[email protected]", account=AccountModel(name="username")) 
email2 = EmailModel(email="[email protected]", account=AccountModel(name="username")) 

通常SQLAlchemy的將創建一個帳戶的兩個條目,每個電子郵件地址鏈接到這個。如果我將accountname設置爲唯一的sqlalchemy正在拋出一個異常,它告訴我關於具有相同值的條目已經存在。這使得所有的意義和工作如預期。

現在我想通了,我自己的一種方式,它允許提到的代碼,只是通過覆蓋的構造的AccountModel類創建一個帳戶只有一次:

def __new__(*cls, **kw): 
    if len(kw) and "name" in kw: 
     x = session.query(cls.__class__).filter(cls[0].name==kw["name"]).first() 
     if x: return x 
    return object.__new__(*cls, **kw) 

這是可以正常使用的我。但問題是:

  • 這是正確的方法嗎?
  • 是否有sqlalchemy方式實現相同?

我使用的是最新的0.8.4版本的SQLAlchemy和Python 2.7.x

感謝所有幫助:)

回答

1

我認爲,因爲它創建了一個它不是實現這一目標的最佳途徑您的構造函數對全局變量session的依賴關係,並且還會以意外的方式修改構造函數的行爲(畢竟,new預計會返回新對象)。例如,如果有人在兩個並行會話中使用您的類,代碼將會失敗,他將不得不深入代碼以查找錯誤。

我不知道實現這一目標的任何「SQLAlchemy的」方式,但我建議創建一個函數createOrGetAccountModel

def createOrGetAccountModel(**kw): 
    if len(kw) and "name" in kw: 
     x = session.query(AccountModel).filter_by(name=kw["name"]).first() 
     if x: return x 
    return AccountModel(**kw) 
+0

你的權利!它不是關於代碼可維護性的完美解決方案。但是__new__不是處理對象創建的完美場所嗎? –

+0

是的,但你並沒有(總是)創建新的對象,所以'__new__'是誤導性的。如果你寫'x = SomeClass()',大家都會期望'x'成爲一個新對象... – MartinStettner

相關問題