sqlalchemy子查詢參與比較篩選
阿新 • • 發佈:2019-02-18
今天專案中遇到一個用子查詢的欄位進行篩選的查詢,先放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
)
發現報了兩張種錯
- TypeError: unsupported operand type(s) for +: 'Query' and 'int'
- 查詢出來怎麼都沒結果
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重新命名一下