2013-06-01 68 views
1

在我的圖像標籤應用程序中,我想要顯示分配給圖像的標籤列表以及標籤標籤類型和用戶信息。 主表是imageLabel。表auth_user和labelType包含標籤的附加信息。web2py中的雙連接。如何在web2py中應用這個SQL?

你能幫我將這個SQL語句來的web2py:

SELECT labelType.name, imageLabel.labelValue, auth_user.first_name, auth_user.last_name from imageLabel 
LEFT JOIN labelType 
ON imageLabel.labelId = labelType.id 
LEFT JOIN auth_user 
ON imageLabel.userId = auth_user.id 
WHERE imageLabel.imageId = 581 
ORDER BY labelType.name 

數據模型是這樣的:

db.define_table('labelType', 
    Field('name','string'), 
) 
db.define_table('imageLabel', 
    Field('imageId','string'), 
    Field('labelId','integer'), 
    Field('userId','integer'), 
    Field('labelValue','text'), 
) 
db.define_table('image', 
    Field('imageId','string') 
) 
# + built-in auth tables 

我的嘗試是:

labels = db((db.imageLabel.id == db.labelType.id)).select( 
     db.imageLabel.labelValue, db.labelType.name, db.auth_user.first_name, db.auth_user.last_name, db.imageLabel.labelTimeStamp, 
     left=db.auth_user.on(db.imageLabel.userId==db.auth_user.id) 
     ) 

哪個abviously不起作用,因爲代碼中沒有WHERE imageLabel.imageId = 581部分。我無法弄清楚如何使用WHERE與2沿web2py的「加入」 :-(

非常感謝您事先的任何幫助

編輯:!解決方案從安東尼閱讀的答案後:

labels = db(
    db.imageLabel.imageId == img.id 
).select(
    db.imageLabel.labelValue, 
    db.labelType.name, 
    db.auth_user.first_name, 
    db.auth_user.last_name, 
    db.imageLabel.labelTimeStamp, 
    left=[ 
     db.labelType.on(db.imageLabel.labelId == db.labelType.id), 
     db.auth_user.on(db.imageLabel.userId==db.auth_user.id) 
    ], 
    orderby=~db.labelType.name 
) 

回答

5

一般情況下,選擇看起來像db(query).select(...)的是,query部分表示WHERE條款如果有多個WHERE條款,你只需要使用&操作人員:

db((condition 1) & (condition 2) & ...) 

至於left joins,該.select()方法的left參數可以是一個列表,如果你需要指定多個左聯接:

left=[db.auth_user.on(db.imageLabel.userId==db.auth_user.id), 
     db.labelType.on(db.imageLabel.labelId==db.labelType.id)] 

但是,目前還不清楚,你真的想左聯接在這裏 - - 你可能只是想內部連接(可使用join參數的.select()方法來指定,或者更簡單地作爲查詢條件):

db((db.imageLabel.labelId == db.labelType.id) & # joins imageLabel and labelType 
    (db.imageLabel.userId == db.auth_user.id) & # joins imageLabel and auth_user 
    (db.imageLabel.imageId == 581))\ 
    .select(db.imageLabel.labelValue, db.labelType.name, db.auth_user.first_name, 
      db.auth_user.last_name, db.imageLabel.labelTimeStamp) 

此外,你應該指定三個「ID」字段引用類型字段:

db.define_table('imageLabel', 
    Field('imageId', 'reference image'), 
    Field('labelId', 'reference labelType'), 
    Field('userId', 'reference auth_user'), 
    Field('labelValue', 'text'), 
) 

最後,爲什麼你需要一個圖像標識字符串字段? db.image表已經有一個自動遞增的整數「id」字段作爲表的主鍵並唯一標識每個圖像。

+0

+1:謝謝你寶貴的建議!使用列表作爲左值是關鍵!現在它可以工作,我已經將解決​​方案添加到了我的問題中。特別是,非常感謝db()。select()的很好的解釋。我沒有從網上書中得到它。關於[image.imageId],這個名字的確有誤導性。實際上,該字段存儲圖像的32個字符長的散列值,以防止導入現有的圖像。它不是圖像表的主鍵(但它可能是,因爲這些值也是唯一的) –

+0

哦,現在我明白了,在我的模式中還有另一個錯誤。你的意思是imageLabel.imageId。這確實是無稽之談。再次感謝! –