2012-02-14 40 views
0

用下面的表格和映射Sqlalichemy:在parent屬性加載相關對象的ID

class A: 
    def __init__(self): 
     self.id = None 
     self.b_ids = {} 
     self.b_s = {} 

class B: 
    def __init__ (self): 
     self.id = None 
     self.a_id = None 
     self.a = None 

a = Table('t_a', meta, 
    Column('id',Integer, autoincrement=True, primary_key=True), 
    ) 

b = Table('t_b', meta, 
    Column('id',Integer, autoincrement=True, primary_key=True), 
    Column('a_id', Integer, ForeignKey('t_a.id')), 
    ) 

mapper(A, a) 
mapper(B, b, properties={'a' : relationship(A, backref="b_s")}) 

當我打開「A」我可以在「B_S」屬性相關的「B」的對象。但是我想要的是A.b_ids屬性中相關Bs的ID列表。有沒有辦法做到這一點?

我嘗試:

mapper(A, a, properties={'b_ids' : 
         column_property(select(
               [b.c.id], 
               a.c.id==b.c.a_id)) 
         }) 

但它給錯誤: 'ProgrammingError:(ProgrammingError)通過用作表達一個子查詢返回多於一行'

回答

4

column_property()被用於添加另一列的SELECT語句,像這樣的:

SELECT a.x, a.y, (SELECT b.id FROM b where a.id=b.a_id) AS b_id FROM a 

在SQL中,這是SELECT語句的列子句中的子查詢,它需要準確地返回每行一行/列 - 在SQLAlchemy中,我們稱之爲「標量選擇」。

在這種情況下,您正在查找一個列表,因此它沒有嵌入到主列條目中。這就是數據庫爲此返回錯誤的原因。您的映射已經包含「bids」列表,其格式爲「b_s」。你只是想提取的「ID」,這樣就可以很容易地與聯想代理來完成:

from sqlalchemy.ext.associationproxy import association_proxy 

class A(object): 
    # ... other things 
    b_ids = association_proxy('b_s', 'id') 

當您訪問「a.b_ids」,這將着眼於「B_S」內的每個條目並提取「id」屬性,返回一個與「b_s」集合類型兼容的集合,在這種情況下,它是一個Python列表。

+0

非常感謝您的回答。我已經添加了一些疑問作爲答案,因爲它不符合評論。 – Litty 2012-02-15 04:28:40

0

我試着把map_proxy放在mapper屬性中。但它不允許。另外,鍊金術文檔中提到「代理是一個Python屬性,與映射關係不同,在您的類中定義」。所以我認爲我們不能保留這個內部mapper()的映射。

無論如何,我無法修改模型類作爲其生成的代碼。所以我試了下面:

a = Table('t_a', meta, 
    Column('id',Integer, autoincrement=True, primary_key=True), 
    ) 

b = Table('t_b', meta, 
    Column('id',Integer, autoincrement=True, primary_key=True), 
    Column('a_id', Integer, ForeignKey('t_a.id')), 
    ) 

mapper(A, a) 
mapper(B, b, properties={'a' : relationship(A, backref="b_s")}) 

A.b_ids=association_proxy('b_s', 'id') 

這似乎是工作。那麼這樣做可以嗎?或者,還有更好的方法?

Regards, Litty

+0

如果你已經有了一個類,那麼在事實之後堅持屬性是如何做的,是的。 – zzzeek 2012-02-15 18:55:36

相關問題