подзапрос в операторе выбора - PullRequest
1 голос
/ 31 декабря 2010

У меня есть две таблицы (альбомы, изображения) в отношении один ко многим, и я хочу отобразить детали каждого альбома с одним изображением, поэтому у меня есть следующий запрос

select albums.name
    , (
      select pictures.path 
      from pictures 
      where pictures.albumid = albums.id 
      limit 1
    ) as picture 
from albums 
where ...

Сейчас я пытаюсь создать это на Pylons с sqlalchemy. Я попытался сделать следующее

picture = Session.query(model.Picture)

sub_q = picture.filter_by(albumid = model.Album.id).limit(1).subquery()

album_q = Session.query(model.Album, sub_q)

result = album_q.all()

, но при этом создается следующее утверждение, отображающее неверное изображение, поскольку альбомы альбомов включены в подзапрос

select albums.name
    , (
      select pictures.path 
      from pictures, albums 
      where pictures.albumid = albums.id
    ) 
from albums 
where ...

Я делаю это неправильно? Возможно ли это в sqlalchemy ?.

Это прекрасно работает. Извините, но я забыл сказать, что использую отражение sqlalchemy. Я попытаюсь сделать ссылку на объект и посмотреть, работает ли он.

1 Ответ

1 голос
/ 04 января 2011

Если я понимаю основную предпосылку вопроса (по общему признанию, это немного неясно), это звучит, если использовать отношения , которые могли бы достичь этого лучше. Из того, что я собираю, у картинки есть один альбом, а у альбома много картинок? Во всяком случае, это несколько не имеет значения, так как здесь важна концепция отношений.

Вы не указали, как настроена ваша модель, но, используя декларативный синтаксис , вы можете определить таблицы, как показано ниже:

class Album(Base):
    __tablename__ = 'albums'
    id = Column(Integer, Sequence('album_id_sequence'), primary_key=True)

class Picture(Base):
    __tablename__ = 'pictures'
    id = Column(Integer, Sequence('picture_id_sequence'), primary_key=True)
    albumid = Column(Integer, ForeignKey('albums.id'))
    picture = Column(String(99))
    album = relationship('Album', backref=backref('pictures'))

Sqlalchemy берет на себя всю тяжелую работу за вас. Теперь у каждой картинки есть свойство album, которое можно вызывать через picture.album. В коде это выглядит так:

pictures = session.query(Picture).all()
for picture in pictures:
    for album in picture.albums:
        # do stuff with album

И наоборот, если у вас есть альбом, вы можете получить изображение (это то, что делает обратная ссылка в определении отношений):

albums = session.query(Album).all()
for album in albums:
    album.picture  # the picture object related to the album

Я не тестировал код, поэтому есть вероятность, что есть опечатки, но, надеюсь, вы поймете общую идею.

...