2012-09-26 21 views
22

Necesito ayuda para crear la consulta SqlAlchemy.SqlAlchemy y Flask, cómo consultar la relación muchos a muchos

Estoy haciendo un proyecto de Flask donde estoy usando SqlAlchemy. Creé 3 tablas: Restaurant, Dish y restaurant_dish en mi archivo 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) 

He añadido datos a la tabla restaurant_dish y debería estar funcionando correctamente. Donde necesito ayuda es entender cómo obtener un plato usando el restaurante correctamente. Prima de SQL sería algo como esto:

SELECT dish_id FROM restaurant_dish WHERE restaurant_id == id 

Lo que he logrado conseguir hecho pero no funciona:

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

Gracias por la ayuda y también apreciar tutoriales que me puede apuntar en la dirección correcta (la documentación oficial pasa por mi cabeza).

Respuesta

43

La semántica de la relación no se ve bien. Creo que debe ser algo como:

class Restaurant(db.Model): 
    ... 

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

Entonces, para recuperar todos los platos de un restaurante, que puede hacer:

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

Esto debe generar una consulta como:

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

Gracias. Esa era la forma correcta de hacerlo. :) – cancerballs

+4

¡Después de buscar horas, 'Dish.restaurant.any' era exactamente lo que estaba buscando! +1 a ti! – Matthew

+1

esta respuesta es mejor que cualquier documentación. – user455318

Cuestiones relacionadas