Мне нужна помощь в создании запроса SQL, который будет возвращать коктейль из базы данных, учитывая, что я предоставил все ингредиенты, входящие в этот коктейль
Так, например, я хочу, чтобы строка «Gin and Tonic» возвращалась, только если я предоставил правильные идентификаторы для Gin (id - 1) и Tonic (id - 2). Я только поставляю «Тоник», я не должен возвращаться обратно
Я использую SQLAlchemy и Flask, но мне все еще не удается обернуть голову, как запрос будет работать вообще
Вот так выглядит структура моей таблицы
+-------------------+
| Tables_in_my_database |
+-------------------+
| cocktails |
| ing_in_cocktails |
| ingredients |
+-------------------+
Это мой коктейльный столик
+----+----------------+-------+---------+
| id | name | glass | finish |
+----+----------------+-------+---------+
| 1 | white russisan | rocks | stirred |
| 2 | gin and tonic | rocks | stirred |
+----+----------------+-------+---------+
Это моя таблица ингредиентов
+----+---------+----------+
| id | name | ing_type |
+----+---------+----------+
| 1 | vodka | fruit |
| 2 | kahluha | fruit |
| 3 | gin | fruit |
| 4 | tonic | fruit |
+----+---------+----------+
А это моя реляционная таблица
+----+-------------+--------+
| id | cocktail_id | ing_id |
+----+-------------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 3 |
| 4 | 2 | 4 |
+----+-------------+--------+
Вот соответствующие модели SQLAlchemy
class Cocktail(db.Model):
__tablename__ = 'cocktails'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
glass = db.Column(db.String(20), nullable=False)
finish = db.Column(db.String(20), nullable=True)
ingredients = db.relationship(
'Ingredient',
secondary=ing_in_cocktails,
backref=db.backref('cocktails', lazy='dynamic')
)
class Ingredient(db.Model):
__tablename__ = 'ingredients'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
ing_type = db.Column(db.String(20), nullable=False)
ing_in_cocktails = db.Table(
'ing_in_cocktails',
db.Column('id', db.Integer, primary_key=True),
db.Column('cocktail_id', db.Integer, db.ForeignKey('cocktails.id')),
db.Column('ing_id', db.Integer, db.ForeignKey('ingredients.id'))
)
Этот запрос помог мне пройти большую часть пути, но проблема в том, что он возвращает «Джин-тоник», если я предоставлю какой-либо ингредиент в коктейле
# problematic because this returns "Gin and Tonic," despite not passing
# all the ingredients
Cocktail.query.join(ing_in_cocktails).filter(ing_in_cocktails.columns.ing_id.in_([3]))
и приведенный выше запрос переводится в этот SQL
SELECT cocktails.id AS cocktails_id, cocktails.name AS cocktails_name, cocktails.glass AS cocktails_glass, cocktails.finish AS cocktails_finish
FROM cocktails INNER JOIN ing_in_cocktails ON cocktails.id = ing_in_cocktails.cocktail_id
WHERE ing_in_cocktails.ing_id IN (%(ing_id_1)s)