我需要比较来自2个不同数据库的同一模型中的2个查询集。
我期待它们之间的区别。在这种情况下,我只从两个数据库中获取一个列(charfield)并想要比较这个“列表”,即使用集合的集合和差异方法会很好。
但是我不能简单地减去查询集,也可以设置(查询集)和列表(查询集) - 这不会给我任何东西(不是错误),即
diff_set = set(articles1) - set(articles2)
我动态切换数据库,制作2个查询集并尝试比较它们(过滤或排除)
articles1 = list(Smdocuments.objects.using('tmp1').only('id').filter(doctype__exact='CQ'))
# right connection
connections.databases['tmp2']['HOST'] = db2.host
connections.databases['tmp2']['NAME'] = db2.name
articles2 = list(Smdocuments.objects.using('tmp2').only('id').filter(doctype__exact='CQ'))
# okay to chain Smdocuments objects, gives all the entries
all = list(chain(articles1, articles2))
# got nothing, even len(diff_set) is none
diff_set = set(articles1) - set(articles2)
# this one raise error Subqueries aren't allowed across different databases.
articles_exclude = Smdocuments.objects.using('tmp1').only('id').filter(doctype__exact='CQ')
len(articles1)
diff_ex = Smdocuments.objects.using('tmp2').only('id').filter(doctype__exact='CQ').exclude(id__in=articles_exclude)
len(diff_ex)
diff_ex引发错误
不允许跨不同数据库使用子查询。强迫内心 要使用
list(inner_query)
评估查询。
因此,“模型对象”不易操作,差异数据库之间的查询集也是如此。
我知道,这不是一个好的数据库方案,但它是另一个分布式数据库的应用程序,我需要比较它们。
通过一列进行比较就足够了,但可能比较完整的查询集将适用于未来。 或者,我应该将queryset转换为list并比较原始数据吗?
答案 0 :(得分:1)
您的问题实际上并不清楚您的实际期望,但无论如何这里有一些提示:
首先,模型实例(假设它们是相同模型的实例)比较它们的主键值,它也用作词典和集合的哈希值,因此如果要比较底层数据库记录,则不应该在模型实例上工作,但在原始db值上作为元组或dicts的列表。您可以使用(分别为)Queryset.values_list()
或Queryset.values()
来获取这些内容 - 不要忘记{0}{12}
他们,这样您才真正得到list()
而不是list
。
这将我们带到了第二个重点:虽然将自己呈现为列表 - 喜欢(因为它们支持queryset
,迭代,下标和 - 有一些限制 - 切片),len()
不是{ {1}}。你不能比较两个查询集(你可以,但他们可以比较身份,这意味着两个查询集只有在它们实际上是同一个对象时才相等),更重要的是,使用查询集作为参数a' field__in ='查找将产生一个SQL子查询,其中传递一个正确的列表会产生一个简单的字段IN(...)' where子句。这解释了Querysets
方法所带来的错误。
简而言之,如果您想要有效地比较数据库行,您需要:
lists