1

relationship()OUTER JOINを使用して、結合するものがある場合に2番目のテーブルに結合するようにしようとしています。私は現在これを行う方法に固執していますが、、、およびの正しい組み合わせを理解できないoptions()ようrelationship()ですouterjoin()

次のテーブルがあり、アプリケーションIDとartistID(関数によって提供される)の行が存在する場合、AppLikeをApplicationに結合しようとしています。

追加情報を提供させていただきます。以下に示すように、すでに1つの結合が機能していますが、それに一致する行が常にあります。

from sqlalchemy import Column
from . import Base
from . import DBSession
from sqlalchemy.dialects.mysql import (
    INTEGER,
    VARCHAR,
    TEXT,
    TINYINT,
    )
from sqlalchemy.sql import and_
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, joinedload
import time

# 0 = new
# 1 = Denied
# 2 = Accepted
def getNewApplications(artistID):
    query =  DBSession.query(Application).\
        options(joinedload('pieces')).\
        options(joinedload('vote')).\
        filter(AppLike.artist_id==artistID).\
        filter(Application.approved==0)
        #join(AppPiece, Application.app_id==AppPiece.app_id).\

        #outerjoin(AppLike, and_(Application.app_id==AppLike.app_id,
        #    AppLike.artist_id==artistID)).\

    import pdb; pdb.set_trace()
    return query.all()    

class Application(Base):
    """ The SQLAlchemy declarative model class for a FileFavorite object. """
    __tablename__ = 'applications'
    __table_args__ = {
        'mysql_engine': 'InnoDB',
        'mysql_charset': 'utf8'
    }

    app_id = Column(INTEGER(11), autoincrement=True, primary_key=True, nullable=False)
    name = Column(VARCHAR(64), nullable=False)
    nickname = Column(VARCHAR(64), nullable=False)
    email = Column(VARCHAR(255), nullable=False)
    description = Column(TEXT(), nullable=False)
    profile_link = Column(VARCHAR(128), nullable=False)
    location = Column(VARCHAR(64), nullable=False)
    approved = Column(TINYINT(4), nullable=False)
    pieces = relationship("AppPiece", lazy='joined')
    vote = relationship("AppLike", lazy='joined')

    def __init__(self, name, nickname, email, desc, profileLink,
                 location, approved):
        self.name = name
        self.nickname = nickname
        self.email = email
        self.description = desc
        self.profile_link = profileLink
        self.location = location
        self.approved = approved

class AppPiece(Base):
    """ The SQLAlchemy declarative model class for a FileFavorite object. """
    __tablename__ = 'app_pieces'
    __table_args__ = {
        'mysql_engine': 'InnoDB',
        'mysql_charset': 'utf8'
    }

    app_piece_id = Column(INTEGER(11), autoincrement=True, primary_key=True, nullable=False)
    app_id = Column(INTEGER(11), ForeignKey('applications.app_id'))
    link = Column(VARCHAR(128), nullable=False)

    def __init__(self, appID, link):
        self.app_id = appID
        self.link = link

class AppLike(Base):
    """ The SQLAlchemy declarative model class for a FileFavorite object. """
    __tablename__ = 'app_likes'
    __table_args__ = {
        'mysql_engine': 'InnoDB',
        'mysql_charset': 'utf8'
    }

    app_id = Column(INTEGER(11), ForeignKey('applications.app_id'))
    artist_id = Column(INTEGER(11), primary_key=True, nullable=False)
    vote = Column(TINYINT(4), nullable=False)

    def __init__(self, appID, artistID, vote):
        self.app_id = appID
        self.artist_id = artistID
        self.vote = vote
4

1 に答える 1

2

絶対に必要ありません。options(joinedload('pieces'))モデルですでに定義されています(lazy='joined')。結合条件はここでは注意が必要な部分であり、そこでもフィルタリングするため、サブクエリを使用して実行する必要があります。したがって、最終的なクエリは次のようになります。

# We do the filtering on AppLike in the subquery and later join
# Application to it.
applike_subq = DBSession.query(AppLike).\
    filter(AppLike.artist_id == artistID).subquery()
query = DBSession.query(Application).\
    outerjoin(applike_subq, Application.vote).\
    filter(Application.approved == 0).all()
于 2013-01-01T18:51:25.390 に答える