- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
跳转到编辑查看更多真实代码示例,更改查询顺序后不起作用
这是我的模型:
class ModelA(models.Model):
field_1a = models.CharField(max_length=32)
field_2a = models.CharField(max_length=32)
class ModelB(models.Model):
field_1b = models.CharField(max_length=32)
field_2b = models.CharField(max_length=32)
ModelA.objects.create(field_1a="1a1", field_2a="1a2")
ModelA.objects.create(field_1a="2a1", field_2a="2a2")
ModelB.objects.create(field_1b="1b1", field_2b="1b2")
ModelB.objects.create(field_1b="2b1", field_2b="2b2")
>>> ModelA.objects.all().annotate(field1=F("field_1a"), field2=F("field_2a")).values("field1", "field2")
[{"field1": "1a1", "field2": "1a2"}, {"field1": "2a1", "field2": "2a2"}]
# model A first, with annotate
query = ModelA.objects.all().annotate(field1=F("field_1a"), field2=F("field_2a"))
# now union with model B, also annotated
query = query.union(ModelB.objects.all().annotate(field1=F("field_1b"), field2=F("field_2b")))
# get only field1 and field2
query = query.values("field1", "field2")
# the results are skewed:
assert list(query) == [
{"field1": 1, "field2": "1a1"},
{"field1": 1, "field2": "1b1"},
{"field1": 2, "field2": "2a1"},
{"field1": 2, "field2": "2b1"},
]
values()
与变量名不匹配,它只是像元组一样遍历对象。
field1
的值实际上是对象的ID,而
field2
是
field1
.
union()
的顺序如何,它都失败了。和
values()
- 现在模型稍微大了一些,似乎不同的字段计数以某种方式混淆了 Django:
# models
class ModelA(models.Model):
field_1a = models.CharField(max_length=32)
field_1aa = models.CharField(max_length=32, null=True)
field_1aaa = models.CharField(max_length=32, null=True)
field_2a = models.CharField(max_length=32)
extra_a = models.CharField(max_length=32)
class ModelB(models.Model):
extra = models.CharField(max_length=32)
field_1b = models.CharField(max_length=32)
field_2b = models.CharField(max_length=32)
# test
ModelA.objects.create(field_1a="1a1", field_2a="1a2", extra_a="1extra")
ModelA.objects.create(field_1a="2a1", field_2a="2a2", extra_a="2extra")
ModelB.objects.create(field_1b="1b1", field_2b="1b2", extra="3extra")
ModelB.objects.create(field_1b="2b1", field_2b="2b2", extra="4extra")
values = ("field1", "field2", "extra")
query = (
ModelA.objects.all()
.annotate(
field1=F("field_1a"), field2=F("field_2a"), extra=F("extra_a")
)
.values(*values)
)
query = query.union(
ModelB.objects.all()
.annotate(field1=F("field_1b"), field2=F("field_2b"))
.values(*values)
)
# outcome
assert list(query) == [
{"field1": "1a1", "field2": "1a2", "extra": "1extra"},
{"field1": "2a1", "field2": "2a2", "extra": "2extra"},
{"field1": "3extra", "field2": "1b1", "extra": "1b2"},
{"field1": "4extra", "field2": "2b1", "extra": "2b2"},
]
最佳答案
经过一些调试和查看源代码后,我知道为什么会发生这种情况。我要做的是尝试解释为什么要这样做annotate
+ values
结果显示 id
上面两种情况有什么区别。
为了简单起见,我还将为每个语句编写可能的结果 sql 查询。
1. annotate
首先但得到values
关于联合查询
qs1 = ModelA.objects.all().annotate(field1=F("field_1a"), field2=F("field_2a"))
select id, field_1a, field_2a, field_1a as field1, field_2a as field2 from ModelA
query
这是以下结果:
qs = qs1.union(qs2)
(select id, field_1a, field_2a, field_1a as field1, field_2a as field2 from ModelA)
UNION
(select id, field_1b, field_2b, field_1b as field1, field_2b as field2 from ModelB)
union
,
combinator
和
combined_queries
设置在
qs.query
生成的sql由
combining the sql生成个人查询。所以,总结一下:
qs.sql == qs1.sql UNION qs2.sql # in abstract sense
qs.values('field1', 'field2')
,
col_count
in 编译器设置为 2,这是字段数。如您所见,上面的联合查询返回 5 列,但在编译器的最终返回结果中,每行是
sliced using
col_count
.现在,这个
results
只有 2 列被传回
ValuesIterable
它在哪里
maps所选字段中的每个名称以及结果列。这就是它如何导致不正确的结果。
annotate
+
values
单个查询,然后执行
union
annotate
会发生什么与
values
一起使用直接地
qs1 = ModelA.objects.all().annotate(field1=F("field_1a"), field2=F("field_2a")).values('field1', 'field2')
select field_1a as field1, field_2a as field2 from ModelA
qs = qs1.union(qs2)
(select field_1a as field1, field_2a as field2 from ModelA)
UNION
(select field_1b as field1, field_2b as field2 from ModelB)
qs.values('field1', 'field2')
执行时,联合查询返回的列数有 2 列,与
col_count
相同这是 2 并且每个字段都与产生预期结果的各个列匹配。
.values
时也有一个场景。之前
union
不会产生正确的结果。原因是在
ModelB
,
extra
没有注释 field 。
ModelA.objects.all()
.annotate(
field1=F("field_1a"), field2=F("field_2a"), extra=F("extra_a")
)
.values(*values)
select field_1a as field1, field_2a as field2, extra_a as extra from ModelA
ModelB.objects.all()
.annotate(field1=F("field_1b"), field2=F("field_2b"))
.values(*values)
select extra, field_1b as field1, field_2b as field2 from ModelB
(select field_1a as field1, field_2a as field2, extra_a as extra from ModelA)
UNION
(select extra, field_1b as field1, field_2b as field2 from ModelB)
extra
的
ModelB
与
field1
混合的
ModelB
.为了确保您得到正确的结果,请确保生成的 SQL 中的字段顺序始终正确 - 带或不带注释。在这种情况下,我会建议注释
extra
在
ModelB
以及。
关于python - Django 中 `annotate` + `values` + `union` 的错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60562759/
我的问题是 this one. 的一个分支 我有一个要验证的注释(比如电话注释)。我可以使用@phone 验证器来检查电话对象是否有效。我还希望能够将此验证器放在包含电话的联系信息对象上。有没有一种方
我的问题是 this one. 的一个分支 我有一个要验证的注释(比如电话注释)。我可以使用@phone 验证器来检查电话对象是否有效。我还希望能够将此验证器放在包含电话的联系信息对象上。有没有一种方
例如 class LoggingService [Inject] (protected val logger: Logger) class LoggingService @Inject (protec
你觉得你是java高手吗? 您是否深谙反射 API 的 secret ? public @interface @a {} public @interface @b {} @Mark public @i
我对 Spring 和 JUnit 非常陌生。我正在尝试为 spring 服务类运行一个简单的 JUnit 测试用例,但它失败了,我得到了这个异常。我还没有编写任何测试,但在实现之前尝试运行。使用to
对于spring和JUnit来说是非常新的东西。 我正在尝试为spring服务类运行一个简单的JUnit测试用例,但是失败了,并且出现了这个异常。我还没有编写任何测试,但是尝试在实现之前进行测试。 使
我有一个实体Test,它将从特征中获取它的属性(和基本方法): class Test { use Trait_title; } trait Trait_title{ /** *
我(当然)正在尝试使用许多我不太了解的构造来维护一个项目。在尝试弄清楚 Spring 中 AOP 使用的过程中,我遇到了带有以下注释的方法: @Around(value = "@annotation(
目前我正在编写一个注释处理器,它将生成新的源代码。该处理器与应用程序本身隔离,因为它是构建项目的一个步骤,我将整个构建系统与应用程序分开。 这就是问题开始的地方,因为我想处理在应用程序中创建的注释。我
我将 Vertx Service Gen 注释处理器与 Kotlin kapt 结合使用。 在注释处理器启动之前,我的 kapt 失败,到处都是以下异常消息: error: scoping const
我很难弄清楚如何从其实际实现类中获取对 java.lang.annotation.Annotation 的引用。 注释本身看起来像这样(来自框架): @Target({ElementType.TYPE
如何创建类似的注释 @Table(name="batch", uniqueConstraints= @UniqueConstraint(columnNames = {"compound_id"
我刚开始使用Spring Boot,我收到这个错误已经有一段时间了,不幸的是无法修复它。从那时起,我一直在谷歌上搜索,但仍然找不到我做错了什么。在我的代码下面找到:。实体。刀。主要。误差率。启动App
输出文本: Execution failed for task ':app:checkDebugDuplicateClasses'. 1 exception was raised by worker
假设我想使用宏注释来复制@specialized(Int) 之类的注释——我知道这很疯狂。像这样的东西: class expand(expanded: Any*) extends Annotation
假设我想使用宏注释来复制@specialized(Int) 之类的注释——我知道这很疯狂。像这样的东西: class expand(expanded: Any*) extends Annotation
注解处理过程中我目前正在处理一个方法的注解: @Override public boolean process(Set elements, RoundEnvironment env) { Mess
我有接口(interface)资源和几个实现它的类,例如音频、视频...此外,我创建了自定义注释MyAnnotation: @MyAnnotation(type = Audio.class) cl
我的项目包括较旧的未注释 Controller 和较新的基于注释的 Controller 。 我使用的是最新的 Spring jar (3.0.5),在我的 dispatcher-servlet.xm
我正在写一些简单的 win32 东西,我正在使用以下 wWinMain int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance
我是一名优秀的程序员,十分优秀!