2012-09-26 17 views
22

Potrzebuję pomocy w tworzeniu zapytania SqlAlchemy.SqlAlchemy and Flask, jak zapytać wiele do wielu relacji

Robię projekt Flask, w którym używam SqlAlchemy. Stworzyłem 3 tabele: Restaurant, Dish i restaurant_dish w moim pliku models.py.

restaurant_dish = db.Table('restaurant_dish', 
    db.Column('dish_id', db.Integer, db.ForeignKey('dish.id')), 
    db.Column('restaurant_id', db.Integer, db.ForeignKey('restaurant.id')) 
) 

class Restaurant(db.Model): 
    id = db.Column(db.Integer, primary_key = True) 
    name = db.Column(db.String(64), index = True) 

    restaurant_dish = db.relationship('Dish', secondary=restaurant_dish, 
     backref=db.backref('dishes', lazy='dynamic')) 


class Dish(db.Model): 
    id = db.Column(db.Integer, primary_key = True) 
    name = db.Column(db.String(64), index = True) 
    info = db.Column(db.String(256), index = True) 

Dodałem dane do tabeli restaurant_dish i powinno działać poprawnie. Gdzie potrzebuję pomocy, to zrozumienie, jak poprawnie uzyskać Dish za pomocą restauracji. Raw SQL byłoby coś takiego:

SELECT dish_id FROM restaurant_dish WHERE restaurant_id == id 

Co udało mi się załatwić, ale nie działa:

x = Restaurant.query.filter_by(Restaurant.restaurant_dish.contains(name)).all() 

Dzięki za pomoc i Doceniam również tutoriale, które może wskazać mi w dobrym kierunku (oficjalna dokumentacja przechodzi mi przez głowę).

Odpowiedz

43

Semantyczny związek nie wygląda dobrze. Myślę, że powinno być coś takiego:

class Restaurant(db.Model): 
    ... 

    dishes = db.relationship('Dish', secondary=restaurant_dish, 
     backref=db.backref('restaurants')) 

Następnie, aby pobrać wszystkie dania dla restauracji, można zrobić:

x = Dish.query.filter(Dish.restaurants.any(name=name)).all() 

ten powinien generować zapytania jak:

SELECT dish.* 
FROM dish 
WHERE 
    EXISTS (
     SELECT 1 
     FROM restaurant_dish 
     WHERE 
      dish.id = restaurant_dish.dish_id 
      AND EXISTS (
       SELECT 1 
       FROM restaurant 
       WHERE 
        restaurant_dish.restaurant_id = restaurant.id 
        AND restaurant.name = :name 
      ) 
    ) 
+0

Dziękuję Ci. To był właściwy sposób, aby to zrobić. :) – cancerballs

+4

Po wyszukiwaniu godzin, 'Dish.restaurant.any' było dokładnie tym, czego szukałem! +1 do ciebie! – Matthew

+1

ta odpowiedź jest lepsza niż jakakolwiek dokumentacja. – user455318

Powiązane problemy