Skip to content

Conversation

Veritogen
Copy link

@Veritogen Veritogen commented Sep 7, 2023

Dear Sector Labs team,

this PR fixes an issue that occurs when we (https://github.com/einhundert) do an annotation that carries the same name as a field of the model whose queryset is being annotated. This only occurs when using PostgresManager of django-postgres-extra as a model manager.

To test the behaviour use the template: psqlextra-template.zip (includes files for using a VS Code devcontainer).

Or create a django project and a new app. Details on dependencies below. Run test without the changes to see what is actually failing. Pull the changes contained in this PR and install them using pip to see the test pass.

requirements.txt for setup:

asgiref==3.7.2
Django==4.2.4
django-postgres-extra==2.0.8
python-dateutil==2.8.2
six==1.16.0
sqlparse==0.4.4
typing_extensions==4.7.1

Paste the following content into your new apps models.py:

from django.db import models
from psqlextra.manager import PostgresManager

# Create your models here.

class Author(models.Model):
    name = models.CharField()


class BaseDataManager(PostgresManager):
    pass


class BaseBook(models.Model):

    id = models.BigAutoField(primary_key=True)
    author = models.ForeignKey(Author, null=False, on_delete=models.CASCADE) # analogue to meter
    type = models.IntegerField(choices=[("1", "Fiction"),
                                        ("2", "Fantasy")], null=False) # analogue to channel
    timestamp = models.DateTimeField(null=False) # analoge to timestamp 
    rating = models.FloatField(null=False, default=0.0) # analogue to value
    objects = BaseDataManager()

    class Meta:
        abstract = True


class Book(BaseBook):

    source = models.CharField(
        choices=[
        ("S", "self written"),
        ("G", "ghost writer"),
        ("C", "copied"),
    ],
        default="C",
        max_length=1,
        db_index=True,
    )

    class Meta:
        index_together = [["type", "author", "timestamp"], ["author", "timestamp"]]
        unique_together = ("type", "author", "timestamp", "source")
 

And the following into the tests.py:

import datetime
from random import uniform
from .models import Author, Book
import pytest
from django.db.models import Min
from django.db.models.functions.datetime import TruncMonth
from zoneinfo import ZoneInfo

@pytest.mark.django_db(True)
def test_models():
    tz = ZoneInfo("Europe/Berlin")
    author_1 = Author.objects.get_or_create(name="Author 1")[0]
    author_2 = Author.objects.get_or_create(name="Author 2")[0]
    for month in range(1, 13):
        for day in range(1, 28):
            for hour in range(0, 24):
                try:
                    Book.objects.create(author=author_1,
                                    timestamp=datetime.datetime(2023, month, day, hour, 0, tzinfo=tz),
                                    type=1,
                                    rating=uniform(0.0, 1000.0))
                    Book.objects.create(author=author_2,
                                    timestamp=datetime.datetime(2023, month, day, hour, 0, tzinfo=tz),
                                    type=2,
                                    rating=uniform(0.0, 1000.0))
                except:
                    print(month, day, hour)
    qs = Book.objects.all()
    qs = qs.filter(author__in = [author_1, author_2],
                   type__in=[1, 2]
                   )
    qs = qs.filter(timestamp__range=
                   (
        datetime.datetime(2023, 3, 15, 0, 0, tzinfo=tz), 
        datetime.datetime(2023, 7, 15, 0,0, tzinfo=tz))
        )
    qs = qs.values("author", "type").annotate(
        timestamp=TruncMonth("timestamp"), # Cause for error is here
        book_number=Min("rating"),
    ).values(
        "author",
        "type",
        "source",
        "timestamp",
        "rating",
    )
    assert len(qs) == 5184

If you need further information, feel free to reach out.
Last but not least, thank you so much for putting your time and energy into this library.

Regards,
Hannes
Backend Developer at EINHUNDERT

@Veritogen Veritogen changed the title Fix *_new suffix not being removed. Fix "*_new" suffix not being removed. Sep 15, 2023
@Veritogen Veritogen merged commit 2d37ee2 into einhundert:master Sep 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants