Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_get_returning_qs does not fetch foreign keys in the RETURNING statement. #10

Closed
proofit404 opened this issue May 31, 2019 · 2 comments · Fixed by #11
Closed

_get_returning_qs does not fetch foreign keys in the RETURNING statement. #10

proofit404 opened this issue May 31, 2019 · 2 comments · Fixed by #11
Assignees
Labels
bug Something isn't working
Milestone

Comments

@proofit404
Copy link

proofit404 commented May 31, 2019

Hi,

Thanks for the amazing library!

I spend some time looking into a strange N+1 issue on our production system. We have a model defining like this:

class Subscription(TimeStampedModel, SoftDeletableModel, UpdateReturningModel):
    member = ForeignKey(
        settings.AUTH_USER_MODEL,
        related_name="subscriptions",
        on_delete=CASCADE,
    )
    unread_count = IntegerField()

We apply this code to make bulk update counters of many users:

def save_unread_counters(users, counter=1):
    return dict(
        models.Subscription.objects.filter(member__in=users)
        .update_returning(unread_count=F("unread_count") + counter)
        .values_list("member_id", "unread_count")
    )

It will generate following SQL queries:

UPDATE "subscription"
SET "unread_count" = ("subscription"."unread_count" + 1)
WHERE ("subscription"."is_removed" = FALSE
       AND "subscription"."member_id" IN (1518, 1519))
RETURNING "id", "created", "modified", "is_removed", "unread_count"

SELECT "subscription"."id",
       "subscription"."member_id"
FROM "subscription"
WHERE "subscription"."id" = 1515

SELECT "subscription"."id",
       "subscription"."member_id"
FROM "subscription"
WHERE "subscription"."id" = 1516

Looks like _get_returning_qs manager method does not take foreign keys into account when it build field argument.

In the values_list method of the ReturningQuerySet have this line https://github.com/M1hacka/django-pg-returning/blob/d615ee52311fa573d528740a5f1136ddd92585ff/src/django_pg_returning/queryset.py#L116
Where getattr of the member_id load it from the database each time.

Regards, Artem.

@M1ha-Shvn M1ha-Shvn added the bug Something isn't working label Jun 1, 2019
@M1ha-Shvn M1ha-Shvn self-assigned this Jun 1, 2019
@M1ha-Shvn M1ha-Shvn added this to the 1.1.1 milestone Jun 1, 2019
@M1ha-Shvn M1ha-Shvn mentioned this issue Jun 1, 2019
@M1ha-Shvn
Copy link
Owner

Will be released with version 1.1.1

@proofit404
Copy link
Author

Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants