【问题标题】:Django Equivalent of SqlAlchemy `any` to filter `WHERE EXISTS`Django 等效于 SqlAlchemy `any` 来过滤 `WHERE EXISTS`
【发布时间】:2016-02-19 06:49:27
【问题描述】:

我有两个模型,SampleRun。一个Sample 可以属于多个Runs。 Run 模型有name,我想用它来过滤Samples;我想找到所有使用给定name 过滤器运行的Samples。在 SqlAlchemy 中,我这样写:

Sample.query.filter(Sample.runs.any(Run.name.like('%test%'))).all()

在 Django 中,我从:

Sample.objects.filter(run__in=Run.objects.filter(name__icontains='test'))

Sample.objects.filter(run__name__icontains='test')

但是这两个都会产生重复,所以我必须在末尾添加.distinct()

当有大量谓词时(因为distinct 操作必须在大量可能的行上运行),使用distinct 的Django 方法性能很差,而SqlAlchemy 运行良好。重复的行来自每个谓词中重复的left outer join

例如:

Sample.objects.filter(Q(**{'run__name__icontains': 'alex'}) |
     Q(**{'run__name__icontains': 'baz'}) | ...)

编辑:为了让这更复杂一点,我确实希望能够拥有如下过滤器:

(Q(**{'run__name__icontains': 'alex'}) | Q(**{'name__icontains': 'alex'})
  & Q(**{'run__name__icontains': 'baz'}) | Q(**{'name__icontains': 'baz'}))

其中有一个 SQLAlchemy 查询,例如:

clause1 = Sample.runs.any(Run.name.like('%alex%')) | Sample.name.like('%test%')
clause2 = Sample.runs.any(Run.name.like('%baz%')) | Sample.name.like('%baz%')
Sample.query.filter(clause1 & clause2)

【问题讨论】:

    标签: django django-models sqlalchemy django-orm


    【解决方案1】:

    假设这是你的 models.py:

    from django.db import models
    
    class Sample(models.Model):
        name = models.CharField(max_length=255)
    
    class Run(models.Model):
        name = models.CharField(max_length=255)
        sample = models.ForeignKey(Sample)
    

    因为我无法弄清楚如何在不使用“distinct”或不使用“raw”的情况下执行此操作(其中,如果您正在形成自己的 SQL 代码,并且不能依赖 ORM ,那么重点是什么 :p),我建议尝试用 SQLAlchemy 替换 Django ORM,或者将它们一起使用,因为理论上这会起作用。对不起,我帮不上什么忙:(

    这是一篇近期发布的博文,可以帮助您做到这一点: http://rodic.fr/blog/sqlalchemy-django/

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-09
    • 2020-12-24
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 2011-08-22
    • 2015-03-31
    相关资源
    最近更新 更多