1. 程式人生 > >sqlalchemy子查詢參與比較篩選

sqlalchemy子查詢參與比較篩選

今天專案中遇到一個用子查詢的欄位進行篩選的查詢,先放Model

class HomeKeep_staff(Base):
    '''
    家政服務員工
    '''
    __tablename__ = 'homeKeep_staff'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    sex = Column(Integer, nullable=False, default=0)
    photo = Column(Integer, default=config.DEFAULT_PHOTO)
    birth = Column(Integer, nullable=False)
    homeKeep_id = Column(Integer, ForeignKey('homeKeep.id'), nullable=False)
    homeKeep = relationship('HomeKeep', backref='staffs')
    introduce = Column(String)
    diploma = Column(String)

class HomeKeep_type(Base):
    '''
    家政服務類別
    '''
    __tablename__ = 'homeKeep_type'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False, unique=True)
    unit = Column(String, nullable=False)
    homeKeep_staffs = relationship('HomeKeep_staff_homeKeep_type')

class HomeKeep_staff_homeKeep_type(Base):
    '''
    員工技能價格
    '''
    __tablename__ = 'homeKeep_staff_homeKeep_type'
    id = Column(Integer, primary_key=True)
    homeKeep_staff_id = Column(Integer, ForeignKey('homeKeep_staff.id'), nullable=False)
    homeKeep_staff = relationship('HomeKeep_staff', backref='homeKeep_staff_homeKeep_types')
    homeKeep_type_id = Column(Integer, ForeignKey('homeKeep_type.id'), nullable=False)
    homeKeep_type = relationship('HomeKeep_type', backref='homeKeep_staff_homeKeep_types')
    price = Column(Float, nullable=False, default=0.0)



class HomeKeep(Base):
    '''
    家政服務中心
    '''
    __tablename__ = 'homeKeep'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False, default='未命名的家政服務中心')
    introduce = Column(String)
    shopKeeper_id = Column(Integer, ForeignKey('shopKeeper.id'), nullable=False)
    ShopKeeper = relationship('ShopKeeper', backref=backref("homeKeep", uselist=False))
    range_dis = Column(Integer)
    lng = Column(FLOAT)
    lat = Column(FLOAT)
    address = Column(String)
    is_sell = Column(Integer, nullable=False, default=0)


    area_id = Column(Integer, ForeignKey('config_area.id'), nullable=False)
    area = relationship('Config_area', backref='homeKeeps')




以上為所用到的四個表的結構

現在所需要查詢的是根據給定的HomeKeep(家政中心)的id陣列,和一個(HomeKeep_staff)員工的id,還有對應的技能(HomeKeep_type)id,求出在給定家政中心列表內工作的,擁有同一技能且價格在原先員工價格上下浮動1000以內的價格

首先查出原先員工的價格的query

origin_price = self.orm.query(HomeKeep_staff_homeKeep_type.price).filter(
            HomeKeep_staff_homeKeep_type.homeKeep_staff_id == HomeKeep_staff.id,
            HomeKeep_staff_homeKeep_type.homeKeep_type_id == originOrder.homeKeep_type_id)


還有現在員工價格的query
 type_staff_price_query = self.orm.query(HomeKeep_staff_homeKeep_type.price).filter(
            HomeKeep_staff_homeKeep_type.homeKeep_staff_id == HomeKeep_staff.id,
            HomeKeep_staff_homeKeep_type.homeKeep_type_id == originOrder.homeKeep_type_id)


下面再基於這兩個個query寫完整的查詢

一開始我是這麼寫的

staffs = self.orm.query(HomeKeep_staff).filter(HomeKeep_staff.id != originOrder.homeKeep_staff_id,
                                                       HomeKeep_staff.homeKeep_id.in_(
                                                           [homeKeep.id for homeKeep in homeKeeps])).filter(
            type_staff_price_query.exists()
        ).filter(
            type_staff_price_query <= origin_price_query+ 1000,
            type_staff_price_query > origin_price_query - 1000

        )


發現報了兩張種錯

  1. TypeError: unsupported operand type(s) for +: 'Query' and 'int'
  2. 查詢出來怎麼都沒結果
第一個問題我把origin_price_query改為了origin_price_query.scalar(),也就是直接查詢出結果再參與查詢 出現了第二個問題 然後我print(type_staff_price_query<=100000) 得到的結果竟然是 false 而不是想象中的sql語句,我猜測query物件沒有過載那些操作符魔法方法,所以不支援直接的加減和比較, 後來改為了
staffs = self.orm.query(HomeKeep_staff).filter(HomeKeep_staff.id != originOrder.homeKeep_staff_id,
                                                       HomeKeep_staff.homeKeep_id.in_(
                                                           [homeKeep.id for homeKeep in homeKeeps])).filter(
            type_staff_price_query.exists()
        ).filter(
            type_staff_price_query.label('type_staff_price_query1') <= originPrice.label('origin_price') + 1000,
            type_staff_price_query.label('type_staff_price_query1') >= originPrice.label('origin_price') - 1000

        )

用一個label函式,label返回的物件過載了操作符,可以進行比較和運算 下次做就注意下子查詢作為欄位最好用label重新命名一下