与Peewee的复杂联合

时间:2014-04-12 19:20:56

标签: mysql sql peewee

提出这个问题相当尴尬,因为它似乎是如此微不足道,但我无法找到有效的解决方案。

我有以下功能:

def planner(departure_id, arrival_id):
    departure = Stop.get(Stop.id == departure_id)
    arrival = Stop.get(Stop.id == arrival_id)
    buses = Bus.select().join(RideStopRelationship).join(Stop).where(Stop.id == departure)
    for bus in buses:
        print bus.line
        for stop in bus.stops:
            print stop.time, stop.stop.name

基于以下模型:

class Stop(BaseModel):
    name = CharField()
    #lat = FloatField()
    #lng = FloatField()

class Bus(BaseModel):
    line = IntegerField()
    number = IntegerField()
    direction = IntegerField()

class RideStopRelationship(BaseModel):
    bus = ForeignKeyField(Bus, related_name = "stops")
    stop = ForeignKeyField(Stop, related_name = "buses")
    time = TimeField()

关键线是Bus.select().join(RideStopRelationship).join(Stop).where(Stop.id == departure)。我试图让所有公共汽车停在departurearrival。但是,上述查询将返回停靠在departure的所有总线。我怎样才能让公共汽车在两个出发点停下来'并且'到达'?

如果我让这个过于复杂(我的模型太复杂,或者我的查询太多),请随时纠正我。

编辑: 有一种方法可行:

buses_departure = Bus.select().join(RideStopRelationship).join(Stop).where(Stop.id == departure)
buses_arrival = Bus.select().join(RideStopRelationship).join(Stop).where(Stop.id == arrival)
buses = Bus.select().where(Bus.id << buses_departure & Bus.id << buses_arrival)

但它应该是一个简单的查询...

1 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

departure = Stop.get(...)
arrival = Stop.get(...)
query = (Bus
         .select(Bus)
         .join(RideStopRelationship)
         .where(RideStopRelationship.stop << [departure, arrival])
         .group_by(Bus)
         .having(fn.Count(Bus.id) == 2))

无关,但需要注意的一点是,由于python评估运算符的方式,您需要在in个查询周围添加括号:

buses = Bus.select().where(
    (Bus.id << buses_departure) & 
    *Bus.id << buses_arrival))