2010-08-03 32 views
1

最近我一直在和Pylons一起工作,非常喜歡SQLAlchemy模型進行數據庫交互。我的網站有一部分雖然我認爲可以從EAV模式中受益。如何結合SQLAlchemy和EAV DB模式的awesomne​​ss?

以此爲我的表例如:

id | userid | type | value 
---+--------+--------|------------ 
1 | 1  | phone | 111 111 111 
---+--------+--------|------------ 
2 | 1  | age | 40 

我可以手動運行之類的查詢下面來提取和更新數據:

SELECT value FROM table WHERE userid=1 AND type='phone' 
UPDATE table SET value=41 WHERE userid=1 AND type='age' 

這很容易和作品......但手動構造查詢不是我的首選方法。我想使用SQLAlchemy創建我的表模型並讓它完成所有工作。

如果我要使用標準架構,每個type有它自己的專欄中,我能做到以下幾點:

data = Session.query(People).filter_by(id=1).first() 
print data.age 

我:

class People(Base): 

    __tablename__ = 'people' 

    id  = Column(Integer, primary_key=True) 
    userid = Column(Integer, ForeignKey('users.id')) 
    phone = Column(Unicode(40)) 
    age  = Column(Integer) 

然後,我可以使用拔出數據希望能夠爲我的EAV模式做同樣的事情。所以基本上,我需要一種擴展SQLAlchemy的方法,並告訴它,當我打電話給data.age時,實際上這意味着我需要SELECT value FROM table WHERE id=1 AND type='age'

這是可行的嗎?或者我會被迫用手動發佈的查詢混亂我的代碼?

回答

4

看看vertical attribute mapping的例子。我認爲這或多或少是你所追求的。這些示例提供了一個類似字典的界面,而不像您的示例中的屬性(可能對任意元數據鍵更好,而不是某些特定屬性)。

如果你寧願單獨映射每個屬性:在文檔中的東西,可能會感興趣:

  • sql expressions as mapped attributes:你怎麼能確實映射到一個SQL表達式,屬性(只讀)
  • changing attribute behaviour,尤其是,使用描述符和自定義比較器:這可以歸結爲對屬性使用普通的python屬性,並且可以在get/set +上執行任何您需要的操作,並可以選擇與其他值(用於查詢)進行比較。
  • associationproxy:基本上提供了一個關係更簡單的觀點。例如,對於您的情況,您可以使用自定義連接條件(不僅是userid,還要指定「age」類型),並使用uselist=False(因爲可以使_age與您的KeyValue(或任何您想要調用它的關係)每個用戶只有一個年齡,你想要一個單一的值,而不是一個列表)。然後,您可以使用age = association_proxy('_age', 'value')使其僅「顯示」該值,而不是整個KeyValue對象。

我想我會與基於垂直屬性映射例如或者去的東西,或者用associationproxy/