Оптимизация django db запросов - PullRequest
0 голосов
/ 25 октября 2018

Я пытаюсь оптимизировать свои запросы к базе данных (mysql) в приложении django.

Вот такая ситуация:

Мне нужно получить некоторые данные о продажах, акции о некоторых продуктах наежемесячно.Это функция

def get_magazzino_month(year, month):
    from magazzino.models import ddt_in_item, omaggi_item, inventario_item
    from corrispettivi.models import corrispettivi_item, corrispettivi
    from fatture.models import fatture_item, fatture, fatture_laboratori_item
    from prodotti.models import prodotti
    qt = 0
    val = 0

    products = prodotti.objects.all()
    invents = inventario_item.objects.all().filter(id_inventario__data__year=year-1)
    fatture_lab = fatture_laboratori_item.objects.all().order_by("-id_fattura__data")

    for product in products:
        inv_instance = filter_for_product(invents, product)
        if inv_instance:
            qt += inv_instance[0].quantita
        lab_instance = fatture_lab.filter(id_prodotti=product).first()
        prezzo_prodotto = (lab_instance.costo_acquisto/lab_instance.quantita - ((lab_instance.costo_acquisto/lab_instance.quantita) * lab_instance.sconto / 100)) if lab_instance else product.costo_acquisto
    return val, qt

Проблема в том, что мне нужно отфильтровать все данные, чтобы получить только нужный мне продукт.Кажется, что опция .filter заставляет django запрашивать базу данных, хотя все данные есть.Я попытался создать функцию для ее фильтрации самостоятельно, но, хотя количество запросов уменьшается, время загрузки резко увеличивается.

Это функция для фильтрации:

def filter_for_product(array, product):
    result = []
    for instance in array:
        if instance.id_prodotti.id == product.id:
            result.append(instance)
    return result

Кто-нибудь когда-либо имел дело с этим видомпроблемы?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Вы можете использовать prefetch_related() для возврата набора запросов связанных объектов и Prefetch() для дальнейшего управления операцией.

from django.db.models import Prefetch

products = prodotti.objects.all().annotate(
    Prefetch(
        'product_set',
        queryset=inventario_item.objects.all().filter(id_inventario__data__year=year-1),
        to_attr='invent'
    )
)

Затем вы можетеполучить доступ к изобретению каждого продукта, как products[0].invent

0 голосов
/ 25 октября 2018

Использование select_related () поможет оптимизировать ваши запросы

Хороший пример того, что делает select_related () и как его использовать, доступен в simpleisbetterthancomplex .

...