如何通过PK升序测试Django QuerySets的排序方式

时间:2014-04-29 19:53:07

标签: python django

class Foo(models.Model):
    name = models.CharField(max_length=10)

    class Meta(object):
        ordering = ('pk', )

我想测试一下这个顺序是否符合预期。

def test_respect_ordering(self):
    Foo.objects.create(name="bar", pk=2)
    Foo.objects.create(name="baz", pk=1)
    results = Foo.objects.all()
    self.assertEqual("baz", results[0].name)
    self.assertEqual("bar", results[1].name)

虽然这可以按照我的预期工作,但无论Meta类或其中定义的排序属性如何,我的测试都会通过。有什么方法可以测试这个代码是否重要?

为什么我要测试这个?我的测试在SQLite中运行,但生产是在mysql中。希望有一天,我们会使用更好的RDMBS,并且PK可能不会在所有这些RDMBS中返回结果。

Django docs表示排序不会自动发生。

1 个答案:

答案 0 :(得分:0)

如果省略ordering类中的Meta属性,生成的SQL查询结果将不会有ORDER BY子句(无论如何,在1.4中)。这意味着您无法依赖行的顺序。

无序SQL查询通常会有一个看似有意义的顺序。这是因为查询计划很可能使用索引来减少查询时间,索引可以在无序查询的行顺序中发挥重要作用。除非另有说明,否则由Django模型生成的表只会在主键上有一个索引,因此通常情况下,“无序”表格会被删除。在主键上排序时,顺序与订单非常相似。

但是,这里绝对不能保证,这个订单不能依赖。查询计划在很大程度上取决于数据库引擎,甚至可以在同一引擎上对非常相似的查询进行大幅度更改。

如果您需要特定订单,则应明确指定所需的订单。这是保证特定订单的唯一可靠方式。