1

在我的图像标签应用程序中,我想显示分配给图像的标签列表以及分配此标签的标签类型和用户信息。主表是 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

数据模型是这样的:

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)
        )

这显然不起作用,因为代码中没有 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
)
4

1 回答 1

5

通常,选择看起来像db(query).select(...). 那query部分代表WHERE条款。如果您有多个WHERE子句,则只需使用&运算符:

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

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

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'),
)

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

于 2013-06-01T22:09:25.847 回答