【发布时间】:2016-02-19 06:49:27
【问题描述】:
我有两个模型,Sample 和 Run。一个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