Aller au contenu

SQL⚓︎

Je regrette de ne pas avoir sauvegardé mes expériences dans ce domaine au cours du temps. C’est d’autant plus frustrant que je me sens très incompétent dans le domaine…

Quelques astuces

  1. Utiliser un timestamp à la place d’un booléen, ce qui permet d’avoir la date d’établissement du booléen envisagé.
  2. Toujours mettre une condition LIMIT, quelle que soit la requête, ça évite de se retrouver avec des problèmes de mémoire plus tard…

Pagination efficace⚓︎

Un fragment issu de cet article. Cette méthode permet de ne pas faire des requêtes de plus en plus lourdes au cours de la pagination lorsque l’offset augmente.

pagination-efficient.sql
1
2
3
4
5
6
7
SELECT * FROM contacts          -- The full data that you want to show your users.
    INNER JOIN (                -- The "deferred join."
        SELECT id FROM contacts -- The pagination using a fast index.
            ORDER BY id
            LIMIT 15 OFFSET 150000
    ) AS tmp using(id)
ORDER BY id                     -- Order the single resulting page as well.

Compter plusieurs fois avec Django⚓︎

Une astuce grâce à ce commentaire dans les tickets Django.

django-annotate-sum.py
from django.db import models
from django.db.models.expressions import RawSQL


class MyModelQuerySet(models.QuerySet):
    def annotate_sum(self, field_name, annotation_name):
        raw_query = f"""
            SELECT SUM({field_name})
            FROM {self.model._meta.db_table} AS model
            WHERE -- add condition here
        """
        annotation = {annotation_name: RawSQL(raw_query, [])}
        return self.annotate(**annotation)

Qui peut ensuite être utilisé ainsi :

1
2
3
4
5
my_instances = (
    MyModel.objects
    .annotate_sum('points', 'points_earned')
    .annotate_sum('points', 'points_spent')
)

Aller plus loin/différemment⚓︎


Dernière mise à jour: 2022-08-18