|
@@ -48,24 +48,35 @@ class WindowFunctionTests(TestCase):
|
|
|
])
|
|
|
|
|
|
def test_dense_rank(self):
|
|
|
- qs = Employee.objects.annotate(rank=Window(
|
|
|
- expression=DenseRank(),
|
|
|
- order_by=ExtractYear(F('hire_date')).asc(),
|
|
|
- ))
|
|
|
- self.assertQuerysetEqual(qs, [
|
|
|
- ('Jones', 45000, 'Accounting', datetime.date(2005, 11, 1), 1),
|
|
|
- ('Miller', 100000, 'Management', datetime.date(2005, 6, 1), 1),
|
|
|
- ('Johnson', 80000, 'Management', datetime.date(2005, 7, 1), 1),
|
|
|
- ('Smith', 55000, 'Sales', datetime.date(2007, 6, 1), 2),
|
|
|
- ('Jenson', 45000, 'Accounting', datetime.date(2008, 4, 1), 3),
|
|
|
- ('Smith', 38000, 'Marketing', datetime.date(2009, 10, 1), 4),
|
|
|
- ('Brown', 53000, 'Sales', datetime.date(2009, 9, 1), 4),
|
|
|
- ('Williams', 37000, 'Accounting', datetime.date(2009, 6, 1), 4),
|
|
|
- ('Wilkinson', 60000, 'IT', datetime.date(2011, 3, 1), 5),
|
|
|
- ('Johnson', 40000, 'Marketing', datetime.date(2012, 3, 1), 6),
|
|
|
- ('Moore', 34000, 'IT', datetime.date(2013, 8, 1), 7),
|
|
|
- ('Adams', 50000, 'Accounting', datetime.date(2013, 7, 1), 7),
|
|
|
- ], lambda entry: (entry.name, entry.salary, entry.department, entry.hire_date, entry.rank), ordered=False)
|
|
|
+ tests = [
|
|
|
+ ExtractYear(F('hire_date')).asc(),
|
|
|
+ F('hire_date__year').asc(),
|
|
|
+ ]
|
|
|
+ for order_by in tests:
|
|
|
+ with self.subTest(order_by=order_by):
|
|
|
+ qs = Employee.objects.annotate(
|
|
|
+ rank=Window(expression=DenseRank(), order_by=order_by),
|
|
|
+ )
|
|
|
+ self.assertQuerysetEqual(qs, [
|
|
|
+ ('Jones', 45000, 'Accounting', datetime.date(2005, 11, 1), 1),
|
|
|
+ ('Miller', 100000, 'Management', datetime.date(2005, 6, 1), 1),
|
|
|
+ ('Johnson', 80000, 'Management', datetime.date(2005, 7, 1), 1),
|
|
|
+ ('Smith', 55000, 'Sales', datetime.date(2007, 6, 1), 2),
|
|
|
+ ('Jenson', 45000, 'Accounting', datetime.date(2008, 4, 1), 3),
|
|
|
+ ('Smith', 38000, 'Marketing', datetime.date(2009, 10, 1), 4),
|
|
|
+ ('Brown', 53000, 'Sales', datetime.date(2009, 9, 1), 4),
|
|
|
+ ('Williams', 37000, 'Accounting', datetime.date(2009, 6, 1), 4),
|
|
|
+ ('Wilkinson', 60000, 'IT', datetime.date(2011, 3, 1), 5),
|
|
|
+ ('Johnson', 40000, 'Marketing', datetime.date(2012, 3, 1), 6),
|
|
|
+ ('Moore', 34000, 'IT', datetime.date(2013, 8, 1), 7),
|
|
|
+ ('Adams', 50000, 'Accounting', datetime.date(2013, 7, 1), 7),
|
|
|
+ ], lambda entry: (
|
|
|
+ entry.name,
|
|
|
+ entry.salary,
|
|
|
+ entry.department,
|
|
|
+ entry.hire_date,
|
|
|
+ entry.rank,
|
|
|
+ ), ordered=False)
|
|
|
|
|
|
def test_department_salary(self):
|
|
|
qs = Employee.objects.annotate(department_sum=Window(
|
|
@@ -96,7 +107,7 @@ class WindowFunctionTests(TestCase):
|
|
|
"""
|
|
|
qs = Employee.objects.annotate(rank=Window(
|
|
|
expression=Rank(),
|
|
|
- order_by=ExtractYear(F('hire_date')).asc(),
|
|
|
+ order_by=F('hire_date__year').asc(),
|
|
|
))
|
|
|
self.assertQuerysetEqual(qs, [
|
|
|
('Jones', 45000, 'Accounting', datetime.date(2005, 11, 1), 1),
|
|
@@ -523,7 +534,7 @@ class WindowFunctionTests(TestCase):
|
|
|
"""
|
|
|
qs = Employee.objects.annotate(max=Window(
|
|
|
expression=Max('salary'),
|
|
|
- partition_by=[F('department'), ExtractYear(F('hire_date'))],
|
|
|
+ partition_by=[F('department'), F('hire_date__year')],
|
|
|
)).order_by('department', 'hire_date', 'name')
|
|
|
self.assertQuerysetEqual(qs, [
|
|
|
('Jones', 45000, 'Accounting', datetime.date(2005, 11, 1), 45000),
|
|
@@ -753,26 +764,32 @@ class WindowFunctionTests(TestCase):
|
|
|
Detail(value={'department': 'HR', 'name': 'Smith', 'salary': 55000}),
|
|
|
Detail(value={'department': 'PR', 'name': 'Moore', 'salary': 90000}),
|
|
|
])
|
|
|
- qs = Detail.objects.annotate(department_sum=Window(
|
|
|
- expression=Sum(Cast(
|
|
|
- KeyTextTransform('salary', 'value'),
|
|
|
- output_field=IntegerField(),
|
|
|
- )),
|
|
|
- partition_by=[KeyTransform('department', 'value')],
|
|
|
- order_by=[KeyTransform('name', 'value')],
|
|
|
- )).order_by('value__department', 'department_sum')
|
|
|
- self.assertQuerysetEqual(qs, [
|
|
|
- ('Brown', 'HR', 50000, 50000),
|
|
|
- ('Smith', 'HR', 55000, 105000),
|
|
|
- ('Nowak', 'IT', 32000, 32000),
|
|
|
- ('Smith', 'IT', 37000, 69000),
|
|
|
- ('Moore', 'PR', 90000, 90000),
|
|
|
- ], lambda entry: (
|
|
|
- entry.value['name'],
|
|
|
- entry.value['department'],
|
|
|
- entry.value['salary'],
|
|
|
- entry.department_sum,
|
|
|
- ))
|
|
|
+ tests = [
|
|
|
+ (KeyTransform('department', 'value'), KeyTransform('name', 'value')),
|
|
|
+ (F('value__department'), F('value__name')),
|
|
|
+ ]
|
|
|
+ for partition_by, order_by in tests:
|
|
|
+ with self.subTest(partition_by=partition_by, order_by=order_by):
|
|
|
+ qs = Detail.objects.annotate(department_sum=Window(
|
|
|
+ expression=Sum(Cast(
|
|
|
+ KeyTextTransform('salary', 'value'),
|
|
|
+ output_field=IntegerField(),
|
|
|
+ )),
|
|
|
+ partition_by=[partition_by],
|
|
|
+ order_by=[order_by],
|
|
|
+ )).order_by('value__department', 'department_sum')
|
|
|
+ self.assertQuerysetEqual(qs, [
|
|
|
+ ('Brown', 'HR', 50000, 50000),
|
|
|
+ ('Smith', 'HR', 55000, 105000),
|
|
|
+ ('Nowak', 'IT', 32000, 32000),
|
|
|
+ ('Smith', 'IT', 37000, 69000),
|
|
|
+ ('Moore', 'PR', 90000, 90000),
|
|
|
+ ], lambda entry: (
|
|
|
+ entry.value['name'],
|
|
|
+ entry.value['department'],
|
|
|
+ entry.value['salary'],
|
|
|
+ entry.department_sum,
|
|
|
+ ))
|
|
|
|
|
|
def test_invalid_start_value_range(self):
|
|
|
msg = "start argument must be a negative integer, zero, or None, but got '3'."
|