microsoft/mssql-django

NotImplemented returned from empty aggregate in Django 4.2

ElRoberto538 opened this issue · 2 comments

Software versions

  • Django: 4.2.7
  • mssql-django: 1.3
  • pyodbc: 5.0.1
  • python: 3.10 - 3.12
  • SQL Server: 2016
  • OS: Ubuntu 20.04

Table schema and Model

class TestModel(models.Model):
    field_1 = models.IntegerField()
    field_2 = models.IntegerField()

Database Connection Settings

DATABASES = {
    'default': {
        'ENGINE': 'mssql',
        'HOST': DB_CREDENTIALS[DB_HOST_TO_USE]['HOST'],
        'USER': DB_CREDENTIALS[DB_HOST_TO_USE]['USER'],
        'PASSWORD': DB_CREDENTIALS[DB_HOST_TO_USE]['PASSWORD'],
        'NAME': DB_CREDENTIALS[DB_HOST_TO_USE]['NAME'],
        'CONN_MAX_AGE': 600,
        'OPTIONS': {
            'driver': 'ODBC Driver 18 for SQL Server',
            'unicode_results': True,
            'host_is_server': True,
            'use_legacy_datetime': True,
            'extra_params': 'TrustServerCertificate=yes',
        },
    },

Problem description and steps to reproduce
Performing an aggregate that is guaranteed to return no results returns { 'test_aggregate': NotImplemented }. e.g.

TestModel.objects.none().aggregate(test_aggregate=Sum('field_1') / Sum('field_2'))

or

TestModel.objects.filter(some_relation_id__in=[]).aggregate(test_aggregate=Sum('field_1') / Sum('field_2'))

Expected behavior and actual behavior
I expect it to return { 'test_aggregate': None } like it does in Django 3, and like it does in Django 4 using the Django supported DBs (e.g. sqlite, postgres etc)

Error message/stack trace
There is none.

Any other details that can be helpful
This bug is only triggered when the queryset is guaranteed to be empty and the DB isn't actually queried before a result is returned - if the query actually runs against the DB but returns an empty queryset (example below) then I get the expected result. Using an older version of pyodbc (4.0.34?) makes this bug occur in both scenarios.

TestModel.objects.filter(some_relation_id__in=[0]).aggregate(test_aggregate=Sum('field_1') / Sum('field_2'))

mShan0 commented

Hi @ElRoberto538, thanks for the report, we'll take a look into this

Hi @ElRoberto538, we have found the issue and are currently in the review process. The fix will be released soon.

Thank you for bringing this to our attention and for using mssql-django!