在web2py中加倍加入.如何在web2py中应用此SQL?

Val*_*itz 1 database join web2py

在我的图像标记应用程序中,我想显示分配给图像的标签列表以及分配了该标签的标签类型和用户信息.主表是imageLabel.表auth_user和labelType包含标签的附加信息.

你能帮我把这个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
Run Code Online (Sandbox Code Playgroud)

数据模型如下:

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
Run Code Online (Sandbox Code Playgroud)

我的尝试是:

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)
        )
Run Code Online (Sandbox Code Playgroud)

这显然不起作用,因为代码中没有WHERE imageLabel.imageId = 581部分.我无法弄清楚如何在web2py中使用WHERE以及2"JOINS":-(

非常感谢您的任何帮助!

编辑:解决方案阅读安东尼的答案后:

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
)
Run Code Online (Sandbox Code Playgroud)

Ant*_*ony 5

一般来说,选择看起来像db(query).select(...).其中的query一部分代表了WHERE条款.如果您有多个WHERE子句,则只需使用&运算符:

db((condition 1) & (condition 2) & ...)
Run Code Online (Sandbox Code Playgroud)

对于左连接,如果需要指定多个左连接left,则.select()方法的参数可以是一个列表:

left=[db.auth_user.on(db.imageLabel.userId==db.auth_user.id),
      db.labelType.on(db.imageLabel.labelId==db.labelType.id)]
Run Code Online (Sandbox Code Playgroud)

但是,目前还不清楚你真的想要左连接 - 你可能只想要内部连接(可以使用方法的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)
Run Code Online (Sandbox Code Playgroud)

此外,您应该将三个"Id"字段指定为引用类型字段:

db.define_table('imageLabel',
    Field('imageId', 'reference image'),
    Field('labelId', 'reference labelType'),
    Field('userId', 'reference auth_user'),
    Field('labelValue', 'text'),
)
Run Code Online (Sandbox Code Playgroud)

最后,为什么需要imageId字符串字段?db.image表已经有一个自动递增的整数"id"字段,用作表的主键并唯一标识每个映像.