使用此代码不断在Django中使用Deepcopy - 如何避免?

时间:2012-07-09 11:55:32

标签: django

我期待postgres需要一些时间,但是我没想到它不会成为瓶颈,我怎么能解决这个问题呢?

2772856 function calls (2578490 primitive calls) in 32.361 seconds

Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
127921/19340    3.670    0.000   11.486    0.001 /usr/lib/python2.7/copy.py:145(deepcopy)
 2240    3.031    0.001    3.244    0.001 {method 'execute' of 'psycopg2._psycopg.cursor' objects}
114402    1.541    0.000    2.348    0.000 /usr/lib/python2.7/copy.py:267(_keep_alive)

----------------------------------------------- -----------------------------------

    suppliers = models.Supplier.objects.all().order_by('company')
    for supplier in suppliers :
        sup = {}
        sup['company'] = supplier.company
        sup['supplies'] = get_supplies(1, supplier.uuid)
        sup['category'] = 'Supplier'
        if isocode == None :
            addresses = models.Address.objects.filter(company = supplier.company)
        else :
            addresses = models.Address.objects.filter(company = supplier.company, country_iso = isocode)
        sup['contacts'] = models.Contact.objects.filter(address__in=addresses)
        company_list.append(sup)

----------------------------------------------- -----------------------------------

def get_supplies (bought_in_controlpanel_id, supplier_uuid) :

    supplier    = None
    activenode  = None

    if supplier_uuid is not None :
        supplier = models.Supplier.objects.get(uuid = supplier_uuid)

    try :
        activenode = boughtin.BoughtInControlPanel.objects.get (pk = 1)
    except :
        pass

    supplies = boughtin.BoughtInControlPanel.objects.filter (parent = activenode)
    for supply in supplies :
        supply.checked  = 0
        supply.disabled = ""
        supply.open     = 0

        if supplier_uuid is not None :
            try    :
                models.Supplies.objects.get(supplier = supplier, bought_in_control_panel = supply)
                supply.checked = 1
            except :
                supply.open    = 1

    return supplies

1 个答案:

答案 0 :(得分:3)

在循环中查询数据库时,性能通常很差。尽量避免这种情况。

为什么不继续使用关系和__in查询? =)

我认为这应该适用于第一个示例的较少的SQL查询:

company_list = models.Supplier.objects.values_list('company', flat=True)

filter_kwargs = dict(address__company__in=company_list)

if isocode is not None:
    filter_kwargs.update(dict(address__company__isocode=isocode))

sup['contacts'] = models.Contact.objects.filter(**filter_kwargs)

关于get_supplies(),我也会在循环中避免Supplies.objects.get(),除非你确定它只会被击中几次。在循环之前收集带有一个较大查询的耗材列表可能会更好,然后只需检查该列表中是否存在所需的项目。虽然您应该对两种变体进行分析并选择较快的变体。