【问题标题】:Raw sql query issue in DjangoDjango中的原始sql查询问题
【发布时间】:2022-06-16 16:41:56
【问题描述】:

我正在尝试进行 SQL 查询以暗示给出here 的答案。

用户建议我尝试做一个原始的 sql 查询来解决。我在暗示他的建议时遇到了问题。

例如,这是我目前所拥有的。

ingredients = ["eggs", "bacon", "salt"]
recipes = Recipe.objects.raw('select whattocook_RecipeIngredients \
    from whattocook_Recipe a \
    inner join whattocook_RecipeIngredients b \
    on a.id = b.recipe_id and b.ingredient in (ingedients) \
    group by recipeingredients \
    having count(*) >= 2')  

但这不起作用。他的回答说这样做

recipe_list = Recipe.objects.raw('select a.*
   from app_Recipe a 
   inner join app_RecipeIngredients b
      on a.id = b.recipe_id and b.ingredient in ("egg", "bacon", "rice")
   group by a.*
   having count(*) >= 2')

maybe replace app_ with your project name, replace a.* with list of column names.

所以我认为我误解了我需要替换哪些列,因为我的代码给了我这个错误。

django.db.utils.ProgrammingError: column "ingedients" does not exist
LINE 1: ...       on a.id = b.recipe_id and b.ingredient in (ingedients...
                                                             ^
HINT:  Perhaps you meant to reference the column "b.ingredient".

我的app叫whattocook,型号如下

class RecipeIngredients(models.Model):
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, null=True)
    ingredient = models.TextField(null=True, blank=True)
    quantity = models.CharField(max_length=10, null=True, blank=True)
    type = models.CharField(max_length=50, null=True, blank=True)
class Recipe(models.Model):
    account = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True, blank=True)
    name = models.TextField(null=True, blank=True)
    slug = models.SlugField(null=False, blank=True, unique=True)
    image_path = models.ImageField(upload_to=MEDIA_URL, null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    preptime = models.IntegerField(null=True, blank=True)
    cookingtime = models.IntegerField(null=True, blank=True)
    cookingtimeoptions = models.CharField(max_length=100, null=True, blank=True)
    preptimeoptions = models.CharField(max_length=100, null=True, blank=True)
    servings = models.CharField(max_length=100, null=True, blank=True)
    rating_value = models.IntegerField(null=True, blank=True)
    rating_count = models.IntegerField(null=True, blank=True)
    categories = models.ManyToManyField('Category', blank=True)
    date_added = models.DateField(auto_now_add=True)

【问题讨论】:

  • 这里有两个很好的答案(一个用于原始查询,一个用于使用带有“普通”django 命令的过滤器进行过滤):stackoverflow.com/questions/23887559/… 再次询问您的问题可能是不好的形式因为您不喜欢原始答案,但我会注意到您没有正确拼写变量名(这是一回事),但您仍然不能只在原始 sql 语句中键入变量名 - 所以作为规则你需要提供参数,这是 sql 如何处理变量输入。
  • @topsail 我同意,尽管我在这种情况下尝试了几次后仍无法回答,但也有助于知道它可以通过 ORM 完成。

标签: python django django-models django-orm


【解决方案1】:

您可以通过以下方式查询:

from django.db.models import Count
ingredients = ["eggs", "bacon", "rice"]
Recipe.objects.filter(
    recipeingredients__ingredient__in=ingredients
).alias(
    ningredient=Count('recipeingredients')
).filter(
    ningredient__gte=len(ingredients)
)

【讨论】:

  • 这似乎有效,一个问题。 ningredient__gte=2 如果成分不同,那个数字需要改变吗?因此,如果说它是 20 种成分的列表,那将是 19 种?
  • @nadermx:我们首先过滤成分列表(['egg', 'bacon', 'rice'],所以ningredient匹配成分的数量,因此这里只能在最多三个。
  • @nadermx: 但是如果你有 20 种成分,并且应该匹配 all,那么你确实应该使用 20。
  • 谢谢,这种情况在搜索中是否也很敏感?
  • @nadermx:是的,所以'egg',将匹配'Egg''EGG'
猜你喜欢
  • 1970-01-01
  • 2013-04-17
  • 2015-11-21
  • 2012-03-16
  • 2012-03-13
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
  • 2011-08-21
相关资源
最近更新 更多