थोक django में मॉडल ऑब्जेक्ट बनाते हैं


90

मेरे पास डेटाबेस में सहेजने के लिए बहुत सी वस्तुएं हैं, और इसलिए मैं उसके साथ मॉडल उदाहरण बनाना चाहता हूं।

Django के साथ, मैं सभी मॉडल इंस्टेंस बना सकता हूं, के साथ MyModel(data), और फिर मैं उन सभी को बचाना चाहता हूं।

वर्तमान में, मेरे पास ऐसा कुछ है:

for item in items:
    object = MyModel(name=item.name)
    object.save()

मैं सोच रहा था कि क्या मैं वस्तुओं की एक सूची को सीधे बचा सकता हूं, जैसे:

objects = []
for item in items:
    objects.append(MyModel(name=item.name))
objects.save_all()

एक लेनदेन में सभी वस्तुओं को कैसे बचाया जाए?


ऐसा लगता है कि गेंद इस कोड के
ticket

1
list.save_all के लिए सोच रहे हैं? आप लगभग अपने आप को सिर्फ विरोधाभास का जवाब दे सकते हैं जो सोच रहे थे और अपने विषय से 2 पहले शब्दों का उपयोग करें।
सोलावोमिर लेनार्ट

जवाबों:


95

django के विकास के रूप में, वहाँ bulk_createएक वस्तु प्रबंधक विधि के रूप में मौजूद है जो इनपुट के रूप में वस्तुओं का एक वर्ग वर्ग निर्माता का उपयोग करके बनाई गई है। django डॉक्स देखें


12
Django के डॉक्स bulk_create: docs.djangoproject.com/en/dev/ref/models/querysets/#bulk-create
funkotron

1
लेकिन याद रखें कि बल्क_क्रिएट की कुछ सीमाएँ होती हैं, जैसे कि अगर यह एक ऑटोफ़िल्ड है जो प्राथमिक कुंजी नहीं बनाता है जो बचा () स्वचालित रूप से करता है।
हितेश गर्ग

@ हितेश गर्ग, क्या यह अब भी सच है?
रायडेल मिरांडा

1
@RaydelMiranda, हाँ यह अभी भी सही है। यह प्रलेखन में वहीं है:If the model’s primary key is an AutoField it does not retrieve and set the primary key attribute, as save() does, unless the database backend supports it (currently only PostgreSQL).
इंटरडिस्ट

1
Django 3.0.x का उपयोग करना और मैं इस बात की पुष्टि bulk_create()करता हूं कि उपयोग करने से कोई संकेत नहीं मिलते हैं। मुझे आश्चर्य है क्योंकि।
ENCHANCE

43

प्रयोग bulk_create()विधि। यह अब Django में मानक है।

उदाहरण:

Entry.objects.bulk_create([
    Entry(headline="Django 1.0 Released"),
    Entry(headline="Django 1.1 Announced"),
    Entry(headline="Breaking: Django is awesome")
])

1
Django 1.10 में परिवर्तित: PostgreSQL का उपयोग करते समय बल्क_क्रिएट () का उपयोग करके बनाई गई वस्तुओं पर प्राथमिक कुंजी सेट करने के लिए समर्थन जोड़ा गया था।
इलाद चांदी

4

मेरे लिए लूप के लिए मैन्युअल लेनदेन हैंडलिंग का उपयोग करने के लिए काम किया (पोस्टग्रैजेस 9.1):

from django.db import transaction
with transaction.commit_on_success():
    for item in items:
        MyModel.objects.create(name=item.name)

वास्तव में यह 'देशी' डेटाबेस बल्क इंसर्ट के समान नहीं है, लेकिन यह आपको ट्रांसपोर्ट / ऑर्म्स ऑपरेशंस / एसक्यूएल क्वेरी एनालिसिस लागत से बचने / डिस्क्राइब करने की अनुमति देता है।


1
यह थोड़ा बदल गया। अब लेन-देन नहीं होता है commit_on_success। आप का उपयोग करना चाहिए transaction.atomic()देखें: stackoverflow.com/questions/21861207/…
t_io

4

कॉलम-अलग की गई फ़ाइल से ई-मेल बनाने के लिए सभी अंडरक्वाइटिंग और अन-एस्केपिंग रूटीन को अलग करने का तरीका यहां दिया गया है:

SomeModel(Model):
    @classmethod
    def from_file(model, file_obj, headers, delimiter):
        model.objects.bulk_create([
            model(**dict(zip(headers, line.split(delimiter))))
            for line in file_obj],
            batch_size=None)

3

एकल लाइन कार्यान्वयन के लिए, आप नक्शे में लंबोदर अभिव्यक्ति का उपयोग कर सकते हैं

map(lambda x:MyModel.objects.get_or_create(name=x), items)

यहाँ, लैम्ब्डा आइटम की सूची के प्रत्येक आइटम को x से मिलाता है और यदि आवश्यक हो तो एक डेटाबेस रिकॉर्ड बनाता है।

लाम्बा दस्तावेज़


आप शायद यह उल्लेख करना चाहते हैं कि पेड ओवर lambdaहोना है :mapitemsmap(lambda name: MyModel.objects.get_or_create(name = name), items)
मनोज गोविंदन

जा, एक और तरीका है जो मैं कहने की कोशिश करता हूं: (:
FallenAngel

2

Create का उपयोग करने से प्रति नए आइटम में एक क्वेरी आएगी। यदि आप INSERT प्रश्नों की संख्या कम करना चाहते हैं, तो आपको कुछ और उपयोग करने की आवश्यकता होगी।

मुझे कुछ सम्मिलित सम्मिलित स्निपेट का उपयोग करने में सफलता मिली है, हालांकि स्निपेट काफी पुराना है। शायद इसे फिर से काम करने के लिए कुछ परिवर्तनों की आवश्यकता है।

http://djangosnippets.org/snippets/446/


2

बल्कॉप्स मॉड्यूल पर इस ब्लॉग पोस्ट को देखें

मेरे django 1.3 ऐप पर, मैंने महत्वपूर्ण स्पीडअप का अनुभव किया है।


-19

सबसे आसान तरीका createप्रबंधक विधि का उपयोग करना है , जो ऑब्जेक्ट को एक ही चरण में बनाता और बचाता है।

for item in items:
    MyModel.objects.create(name=item.name)

+1। यदि nameअद्वितीय और डुप्लिकेट इनपुट संभव हैं, तो इसका उपयोग करना एक अच्छा विचार होगा get_or_create
मनोज गोविंदन 11

16
यह प्रश्न का उत्तर कैसे देता है? Model.objects.create ऑब्जेक्ट के बराबर है = MoModel (..) object.save ()। और यह एक लेन-देन में ऐसा नहीं है ...
automagic
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.