2013-06-01 2 views
1

В моем приложении для маркировки изображений я хочу отобразить список ярлыков, назначенных изображению, а также информацию типа Lable и пользователя, которые назначили эту метку. Основной стол - это изображениеLabel. Таблицы auth_user и labelType содержат дополнительную информацию на этикетке.Двойной JOIN в web2py. Как применить этот SQL в web2py?

Не могли бы вы мне помочь преобразовать этот 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. И я не могу понять, как использовать, где наряду с 2 «СТАЛ» в web2py :-(

Большое спасибо заранее за любую помощь

EDIT: РЕШЕНИЕ После прочтения ответа от Энтони:

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, то 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» с автоматическим приращением, чтобы служить в качестве первичного ключа для таблицы и однозначно идентифицировать каждое изображение.

+0

+1: Благодарим за ценные предложения! Использование списка в качестве левого значения было ключом! Теперь это работает, и я добавил решение к моему вопросу. Особенно большое спасибо за хорошее объяснение для db(). Select(). Я не получил его из онлайн-книги. Что касается [image.imageId], имя действительно вводит в заблуждение. Фактически это поле хранит 32-символьное длинное хэш-значение изображения, чтобы предотвратить импорт существующих изображений. Это не первичный ключ таблицы изображений (однако это может быть, поскольку эти значения также уникальны) –

+0

О, теперь я вижу, в моей схеме была другая ошибка. Вы имели в виду imageLabel.imageId. Это была бессмыслица. Еще раз спасибо! –