Стварэнне аб'ёмных элементаў базы дадзеных эфектыўна?

Я спрабую стварыць Activty аб'ект для вялікіх (300 + у той час) спіс Запыт аб'ектаў. У мяне ёсць адзін ModelForm , які ў цяперашні час размешчаны назад, і мне трэба, каб стварыць паасобныя асобнікі, і прымацаваць іх да майго Запыт праз GenericForeignKey . Давайце пяройдзем да некаторага коду:

<Моцны> models.py:

class InquiryEntry(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField() 
    entry = generic.GenericForeignKey('content_type', 'object_id')

class Inquiry(models.Model):
    entries = models.ManyToManyField('InquiryEntry')
    # And many more fields.
    def add_entry(self, obj):
        entry = self.entries.create(entry=obj)
        self.save()
        return entry

class Activity(models.Model):  
    ts = models.DateTimeField(auto_now_add=True)                  
    due_date = models.DateField(auto_now=False)
    ## And many more fields.

<Моцны> views.py:

def bulk_create_activities(request):
    activity_form = ActivityForm()
    if request.method == "POST":
        activity_form = ActivityForm(request.POST)
        if activity_form.is_valid():    
            pks = [int(x) for x in request.POST.get('pks', '').split(',')]
            for inquiry in Inquiry.objects.filter(pk__in=pks):
                instance = ActivityForm(request.POST).save()
                inquiry.add_entry(instance)     
                inquiry.save()  

Тое, што я шукаю спосаб, каб уставіць іх у базу дадзеных, пераважна ў адзін праход так, што запыт можа быць апрацаваны хутчэй. Я аддаю перавагу, каб не выпусціць на ўзроўні базы дадзеных, так як гэта дадатак разгорнута на некалькіх пастаўшчыкоў баз дадзеных, але калі гэта адзіны спосаб працягнуць, так што ён (прыклады для MySQL і Postgres будзе дзіўным).


Note: I know that there is a bulk_create in the development version, but that is out of the question until there is a stable release.

10

5 адказы

Спрабавалі Ці вы проста складаеце для у транзакцыі пабудаваць? Commit-на поспех здзелкі вы можаце атрымаць велізарныя бонусы хуткасці, таму што запісы канкрэтна запісваюцца на дыск адразу ў аб'ёме, так што СКБД не павінен спыняцца на Fsync() пасля кожнага пункта.

Implementing transactions in recent versions of django is snappy, check out https://docs.djangoproject.com/en/dev/topics/db/transactions/#controlling-transaction-management-in-views

3
дададзена
Падобна на тое, добрая ідэя, але не змянілі прадукцыйнасць вельмі шмат. На 5-10 дзейнасці, гэта было аб павелічэнні хуткасці на 5%. На 100, зніжэнне хуткасці на 10%.
дададзена аўтар Jack M., крыніца
Дзякуй за паказальнік. Гэта выдатная новая функцыя.
дададзена аўтар AgDude, крыніца

Баюся, што вам можа спатрэбіцца ўпасці да DB-API і выкарыстанне cursor.executemany (). См PEP 249 для дэталяў.

1
дададзена

Гэта не робіць ваша масавае дзеянне якой-небудзь больш эфектыўным, але калі Запыт не трэба быць адказаў імгненна на падставе дадзеных, прадстаўленых (я мяркую, што на аснове імя мадэлі), гэта гучыць праца як для чарзе задач, як сельдэрэй.

Карыстальнік атрымае супер хуткі водгук, і вашы працоўныя салера могуць грызці на ім у вольны час. Калі 1,4 стабільная, праверце in_bulk :)

Я б таксама быць зацікаўлены ў агностыку цвёрдых парод метаду базы дадзеных, але ў залежнасці ад сітуацыі гэта можа быць прымальным рашэннем.

Буду глядзець адказы тут ...

0
дададзена

Take a look at http://people.iola.dk/olau/python/bulkops.py

Яна забяспечвае insert_many і update_many функцыі, якія выконваюць адзін запыт. Як адзначае аўтар, вам прыйдзецца зрабіць некаторыя ручной бухгалтэрыю ў пітона для PKS ў многіх многіх адносінах, але як толькі вы іх распрацавалі, вы можаце проста выканаць пару insert_many на Запыт і <код > InquiryEntry .

0
дададзена

Вы можаце быць у стане атрымаць некаторыя падказкі (у тым ліку для розных сістэм БД), гледзячы на ​​SQL Джанго стварае для некаторых выбарачных дадзеных. працуе сервер у рэжыме выпраўленьня ўсе запыты рэгіструюцца. Вы можаце таксама праверыць іх з дапамогай

>>> from django.db import connection
>>> connection.queries
0
дададзена