python - 从查询集中删除一列
问题描述
我不太确定这是一个问题,还是对 Django 的功能请求,或者我让事情变得不必要的复杂。我正在编写一个用户界面,让用户编写查询,我将其转换为 Django 查询集的创建、修改和组合。
该软件使用ply
, (写入p[0]
等于return
),这里有一些语法摘录:
在这里,我将看起来像单词或用点分隔的单词转换为 django 可以识别的东西。
def p_field_fieldname(p):
'field : fieldname'
p[0] = p[1]
def p_field_dot_fieldname(p):
'field : field DOT fieldname'
p[0] = '{}__{}'.format(p[1], p[3])
实现包含在列表中的测试(我正在使用 global search_domain
,这显然会造成麻烦,但这不是重点)。
def p_bfactor_list_comprehension(p):
'bfactor : field IN LBRACKET valuelist RBRACKET'
p[0] = search_domain.objects.filter(**{'{}__in'.format(p[1]): p[4]})
组合bfactor
令牌。
def p_bterm_bfactor(p):
'bterm : bfactor'
p[0] = p[1]
def p_expression_or_bterm(p):
'expression : expression OR bterm'
p[0] = p[1].union(p[3])
def p_bterm_and_bfactor(p):
'bterm : bterm AND bfactor'
p[0] = p[1].intersection(p[3])
到目前为止,一切都很好。我遇到的问题是当我引入聚合函数时,结合其他查询,让用户编写如下内容:
taxon where rank.id>=17 and count(verifications)=0
我正在实现count
,我通过添加一个额外的列并对其进行测试来做到这一点,但是我一直很难尝试将两个查询集、两个子句的结果count(verifications)=0
和rank.id>=17
.
我试过了,但在使用后defer
我没有设法删除该列。
最后,我写了这个非常丑陋的解决方案,
def p_bfactor_aggregate_comparison(p):
'bfactor : aggregate LPAREN field RPAREN operator value'
from django.db.models import Count, Sum # adding field to qs
_, aggregate, _, field, _, operator, value = p
f = {'count': Count, 'sum': Sum}[aggregate]
q = search_domain.objects.annotate(temp_field=f(field))
matching = set(i['id']
for i in q.filter(**{'temp_field__{}'.format(operator): value})
.values('id'))
p[0] = search_domain.objects.filter(id__in=matching)
我的另一个最佳猜测(更准确地说,我希望它会起作用)是:
def p_bfactor_aggregate_comparison(p):
'bfactor : aggregate LPAREN field RPAREN operator value'
from django.db.models import Count, Sum # adding field to qs
_, aggregate, _, field, _, operator, value = p
f = {'count': Count, 'sum': Sum}[aggregate]
q = search_domain.objects.annotate(temp_field=f(field))
p[0] = q.filter(**{'temp_field__{}'.format(operator): value}
).WHATEVERWORKS('temp_field')
然而不幸的是,我没有找到该WHATEVERWORKS
功能。
如果我不删除该列,一旦解析器遇到 AND 或 OR 产品,它就会给出错误django.db.utils.OperationalError: SELECTs to the left and right of INTERSECT do not have the same number of result columns
。
从 2012 年到今年年初,我一直在使用 SQLAlchemy,在那里我已经实现了与此非常相似的东西。使用 Django,我得到的印象是我落后于一个过于聪明的抽象层。
解决方案
推荐阅读
- java - 如何比较两个 JSON 对象或字符串以获得它们之间的差异报告(JAVA)
- typescript - this.constructor 的多态调用
- java - 带有 Hibernate 的 JBoss EAP 6.4 - 在日志文件中隐藏特定的 Oracle 异常
- java - 从静态 html/css/js Web 应用和 .ear 容器生成 .war 文件
- java - Spring中的默认全局错误
- angularjs - 限制嵌套 ng-repeat 的显示条目
- amazon-web-services - AWS Lambda:调用调用 API 失败并显示消息:[object Object]
- c# - 如何仅在 Visual Studio 中启用当前文件的断点?
- mysql - Windows中的mysql差异/增量备份
- python - Python 通过 1 次调用设置更多属性