Django 2.1

Databases




django

Databases

Django सभी डेटाबेस बैकएंड पर अधिक से अधिक सुविधाओं का समर्थन करने का प्रयास करता है। हालाँकि, सभी डेटाबेस बैकएंड एक जैसे नहीं हैं, और हमें डिज़ाइन निर्णय लेने हैं, जिन पर समर्थन करने के लिए और किन मान्यताओं को हम सुरक्षित रूप से बना सकते हैं।

यह फ़ाइल कुछ ऐसी विशेषताओं का वर्णन करती है जो Django उपयोग के लिए प्रासंगिक हो सकती हैं। बेशक, यह सर्वर-विशिष्ट प्रलेखन या संदर्भ मैनुअल के प्रतिस्थापन के रूप में नहीं है।

सामान्य टिप्पणी

लगातार कनेक्शन

लगातार कनेक्शन प्रत्येक अनुरोध में डेटाबेस से एक कनेक्शन को फिर से स्थापित करने के ओवरहेड से बचते हैं। वे CONN_MAX_AGE पैरामीटर द्वारा नियंत्रित होते हैं जो कनेक्शन के अधिकतम जीवनकाल को परिभाषित करता है। इसे प्रत्येक डेटाबेस के लिए स्वतंत्र रूप से सेट किया जा सकता है।

डिफ़ॉल्ट मान 0 , प्रत्येक अनुरोध के अंत में डेटाबेस कनेक्शन को बंद करने के ऐतिहासिक व्यवहार को संरक्षित करता है। लगातार कनेक्शन सक्षम करने के लिए, CONN_MAX_AGE को सकारात्मक संख्या में सेकंड में सेट करें। असीमित लगातार कनेक्शन के लिए, इसे None सेट न करें।

कनेक्शन प्रबंधन

Django डेटाबेस से एक कनेक्शन खोलता है जब यह पहली बार डेटाबेस क्वेरी बनाता है। यह इस कनेक्शन को खुला रखता है और बाद के अनुरोधों में इसका पुन: उपयोग करता है। एक बार जब यह CONN_MAX_AGE द्वारा परिभाषित अधिकतम आयु से अधिक हो जाता है या जब यह अब उपयोग करने योग्य नहीं होता है तो Django कनेक्शन को बंद कर देता है।

विस्तार से, Django स्वचालित रूप से डेटाबेस से एक कनेक्शन खोलता है जब भी उसे एक की आवश्यकता होती है और उसके पास पहले से कोई नहीं होता है - या तो क्योंकि यह पहला कनेक्शन है, या क्योंकि पिछला कनेक्शन बंद था।

प्रत्येक अनुरोध की शुरुआत में, Django कनेक्शन बंद कर देता है अगर यह अपनी अधिकतम आयु तक पहुंच गया है। यदि आपका डेटाबेस कुछ समय के बाद निष्क्रिय कनेक्शन समाप्त करता है, तो आपको CONN_MAX_AGE को कम मूल्य पर सेट करना चाहिए, ताकि Django डेटाबेस सर्वर द्वारा समाप्त किए गए कनेक्शन का उपयोग करने का प्रयास न करें। (यह समस्या केवल बहुत कम यातायात साइटों को प्रभावित कर सकती है।)

प्रत्येक अनुरोध के अंत में, Django कनेक्शन बंद कर देता है यदि यह अपनी अधिकतम आयु तक पहुंच गया है या यदि यह एक अपरिवर्तनीय त्रुटि स्थिति में है। यदि अनुरोधों को संसाधित करते समय कोई डेटाबेस त्रुटियां हुई हैं, तो Django जाँच करता है कि क्या कनेक्शन अभी भी काम करता है, और अगर यह नहीं करता है तो इसे बंद कर देता है। इस प्रकार, डेटाबेस त्रुटियां अधिकांश एक अनुरोध पर प्रभावित होती हैं; यदि कनेक्शन अनुपयोगी हो जाता है, तो अगले अनुरोध को एक नया कनेक्शन मिलता है।

चेतावनियां

चूंकि प्रत्येक थ्रेड अपने स्वयं के कनेक्शन को बनाए रखता है, आपके डेटाबेस में कम से कम एक साथ कनेक्शन का समर्थन होना चाहिए क्योंकि आपके पास वर्कर थ्रेड हैं।

कभी-कभी आपके विचारों के बहुमत से एक डेटाबेस तक नहीं पहुँचा जा सकता है, उदाहरण के लिए क्योंकि यह एक बाहरी प्रणाली का डेटाबेस है, या कैशिंग के लिए धन्यवाद। ऐसे मामलों में, आपको CONN_MAX_AGE को कम मान या यहां तक ​​कि 0 सेट करना चाहिए, क्योंकि यह एक कनेक्शन बनाए रखने के लिए समझ में नहीं आता है जिसका पुन: उपयोग होने की संभावना नहीं है। यह इस डेटाबेस में एक साथ कनेक्शन की संख्या को छोटा रखने में मदद करेगा।

विकास सर्वर प्रत्येक अनुरोध के लिए एक नया थ्रेड बनाता है, जो लगातार कनेक्शन के प्रभाव को नकारता है। विकास के दौरान उन्हें सक्षम न करें।

जब Django डेटाबेस के लिए एक कनेक्शन स्थापित करता है, तो यह बैकेंड के उपयोग के आधार पर उपयुक्त पैरामीटर सेट करता है। यदि आप लगातार कनेक्शन सक्षम करते हैं, तो यह सेटअप हर अनुरोध को दोहराया नहीं जाता है। यदि आप कनेक्शन के आइसोलेशन स्तर या टाइम ज़ोन जैसे मापदंडों को संशोधित करते हैं, तो आपको प्रत्येक अनुरोध के अंत में Django की डिफ़ॉल्ट को पुनर्स्थापित करना चाहिए, प्रत्येक अनुरोध की शुरुआत में एक उचित मूल्य मजबूर करना चाहिए, या लगातार कनेक्शन को अक्षम करना चाहिए।

एन्कोडिंग

Django का मानना ​​है कि सभी डेटाबेस UTF-8 एन्कोडिंग का उपयोग करते हैं। अन्य एन्कोडिंग का उपयोग करने से अनपेक्षित व्यवहार हो सकता है जैसे कि Django में मान्य डेटा के लिए आपके डेटाबेस से "मूल्य बहुत लंबा" त्रुटियां। अपने डेटाबेस को सही तरीके से कैसे सेट करें, इसकी जानकारी के लिए नीचे दिए गए डेटाबेस विशिष्ट नोट्स देखें।

PostgreSQL नोट

Django PostgreSQL 9.4 और उच्चतर का समर्थन करता है। psycopg2 2.5.4 या उच्चतर की आवश्यकता होती है, हालांकि नवीनतम रिलीज की सिफारिश की जाती है।

PostgreSQL कनेक्शन सेटिंग्स

विवरण के लिए HOST देखें।

PostgreSQL के विन्यास का अनुकूलन

Django को अपने डेटाबेस कनेक्शन के लिए निम्नलिखित मापदंडों की आवश्यकता है:

  • client_encoding : 'UTF8' ,
  • default_transaction_isolation : डिफ़ॉल्ट रूप से 'read committed' , या कनेक्शन विकल्पों में निर्धारित मूल्य (नीचे देखें)
  • timezone : 'UTC' जब USE_TZ True , TIME_ZONE मान अन्यथा।

यदि इन मापदंडों में पहले से ही सही मान हैं, तो Django उन्हें हर नए कनेक्शन के लिए सेट नहीं करेगा, जो प्रदर्शन को थोड़ा सुधारता है। आप उन्हें सीधे postgresql.conf या अधिक आसानी से प्रति डेटाबेस उपयोगकर्ता में कॉन्फ़िगर कर सकते हैं।

Django इस अनुकूलन के बिना बस ठीक काम करेगा, लेकिन प्रत्येक नया कनेक्शन इन मापदंडों को सेट करने के लिए कुछ अतिरिक्त क्वेरी करेगा।

अलगाव का स्तर

खुद PostgreSQL की तरह, Django READ COMMITTED आइसोलेशन लेवल को डिफॉल्ट करता है । यदि आपको उच्च अलगाव स्तर की आवश्यकता है जैसे कि SERIALIZABLE REPEATABLE READ या SERIALIZABLE , तो इसे डेटाबेस में अपने डेटाबेस कॉन्फ़िगरेशन के OPTIONS भाग में सेट करें:

import psycopg2.extensions

DATABASES = {
    # ...
    'OPTIONS': {
        'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE,
    },
}

ध्यान दें

उच्च अलगाव स्तरों के तहत, आपके आवेदन को क्रमबद्धता विफलताओं पर उठाए गए अपवादों को संभालने के लिए तैयार किया जाना चाहिए। यह विकल्प उन्नत उपयोगों के लिए डिज़ाइन किया गया है।

varchar और text कॉलम के लिए अनुक्रमणिका

जब अपने मॉडल क्षेत्रों पर db_index=True निर्दिष्ट करते हैं, तो Django आमतौर पर एक एकल CREATE INDEX कथन को आउटपुट करता है। हालाँकि, यदि फ़ील्ड के लिए डेटाबेस प्रकार या तो varchar या text (उदाहरण के लिए, CharField , FileField , और TextField द्वारा उपयोग किया जाता है) है, तो Django कॉलम के लिए एक उपयुक्त PostgreSQL ऑपरेटर वर्ग का उपयोग करने वाला एक अतिरिक्त सूचकांक बनाएगा। अतिरिक्त अनुक्रमणिका आवश्यक रूप से लुकअप को SQL में उपयोग करने वाले लुकअप को निष्पादित करने के लिए आवश्यक है, जैसा कि contains और startswith लुकअप टाइप्स होते हैं।

एक्सटेंशन जोड़ने के लिए माइग्रेशन ऑपरेशन

यदि आपको माइग्रेशन का उपयोग करके PostgreSQL एक्सटेंशन (जैसे hstore , postgis , आदि) जोड़ने की आवश्यकता है, तो CreateExtension ऑपरेशन का उपयोग करें।

सर्वर-साइड कर्सर

QuerySet.iterator() का उपयोग करते QuerySet.iterator() , Django एक सर्वर-साइड कर्सर खोलता है । डिफ़ॉल्ट रूप से, PostgreSQL मान लेता है कि कर्सर प्रश्नों के परिणामों का केवल पहला 10% ही प्राप्त होगा। क्वेरी प्लानर क्वेरी की योजना बनाने में कम समय व्यतीत करता है और परिणाम तेजी से लौटाना शुरू कर देता है, लेकिन यह 10% से अधिक परिणाम प्राप्त होने पर प्रदर्शन को कम कर सकता है। कर्सर क्वेरी के लिए पुनर्प्राप्त की गई पंक्तियों की संख्या पर PostgreSQL की मान्यताओं को cursor_tuple_fraction विकल्प के साथ नियंत्रित किया जाता है।

लेन-देन पूलिंग और सर्वर-साइड कर्सर

लेन-देन पूलिंग मोड (जैसे pgBouncer ) में कनेक्शन पूलर का उपयोग करने के लिए उस कनेक्शन के लिए सर्वर-साइड कर्सर को अक्षम करने की आवश्यकता होती है।

सर्वर-साइड कर्सर एक कनेक्शन के लिए स्थानीय हैं और AUTOCOMMIT True होने पर ट्रांजेक्शन के अंत में खुले रहते हैं। एक बाद के लेनदेन में सर्वर-साइड कर्सर से अधिक परिणाम लाने का प्रयास किया जा सकता है। लेन-देन पूलिंग मोड में, इस बात की कोई गारंटी नहीं है कि बाद के लेनदेन उसी कनेक्शन का उपयोग करेंगे। यदि भिन्न कनेक्शन का उपयोग किया जाता है, तो लेन-देन सर्वर-साइड कर्सर को संदर्भित करते समय एक त्रुटि उठाई जाती है, क्योंकि सर्वर-साइड कर्सर केवल उस कनेक्शन में पहुंच योग्य होते हैं जिसमें वे बनाए गए थे।

DATABASES में कनेक्शन के लिए सर्वर-साइड कर्सर को अक्षम करने के लिए एक समाधान है DISABLE_SERVER_SIDE_CURSORS को True सेट करके।

लेन-देन पूलिंग मोड में सर्वर-साइड कर्सर से लाभ उठाने के लिए, आप सर्वर-साइड कर्सर का उपयोग करने वाले प्रश्नों को करने के लिए डेटाबेस में एक और कनेक्शन स्थापित कर सकते हैं। यह कनेक्शन या तो सीधे डेटाबेस में या सत्र पूलिंग मोड में कनेक्शन पूलर के लिए होना चाहिए।

एक अन्य विकल्प प्रत्येक QuerySet को एक atomic() ब्लॉक में सर्वर-साइड कर्सर का उपयोग करके QuerySet , क्योंकि यह लेनदेन की अवधि के लिए autocommit को निष्क्रिय करता है। इस तरह, सर्वर-साइड कर्सर केवल लेनदेन की अवधि के लिए रहेगा।

ऑटो-इन्क्रिमिंग प्राथमिक कुंजी के मैन्युअल-निर्दिष्ट मान

Django ऑटो-इन्क्रिमिंग प्राथमिक कुंजी को संग्रहीत करने के लिए PostgreSQL के SERIAL डेटा प्रकार का उपयोग करता है। एक sequence कॉलम एक sequence से मानों के साथ आबादी है जो अगले उपलब्ध मूल्य का ट्रैक रखता है। मैन्युअल रूप से एक ऑटो-इन्क्रिमिंग फ़ील्ड के लिए एक मान निर्दिष्ट करना क्षेत्र के अनुक्रम को अपडेट नहीं करता है, जो बाद में संघर्ष का कारण हो सकता है। उदाहरण के लिए:

>>> from django.contrib.auth.models import User
>>> User.objects.create(username='alice', pk=1)
<User: alice>
>>> # The sequence hasn't been updated; its next value is 1.
>>> User.objects.create(username='bob')
...
IntegrityError: duplicate key value violates unique constraint
"auth_user_pkey" DETAIL:  Key (id)=(1) already exists.

यदि आपको इस तरह के मूल्यों को निर्दिष्ट करने की आवश्यकता है, तो तालिका में पहले से मौजूद मूल्य के पुन: उपयोग से बचने के लिए अनुक्रम को बाद में रीसेट करें। sqlsequencereset प्रबंधन आदेश SQL कथन को उत्पन्न करता है।

डेटाबेस डेटाबेस का परीक्षण करें

आप एक template डेटाबेस बनाने के लिए template (उदाहरण के लिए 'template0' ) का उपयोग करने के लिए TEST['TEMPLATE'] सेटिंग का उपयोग कर सकते हैं।

गैर-टिकाऊ सेटिंग्स के साथ परीक्षण निष्पादन में तेजी

आप PostgreSQL को गैर-टिकाऊ होने के लिए परीक्षण निष्पादन समय को तेज़ कर सकते हैं।

चेतावनी

यह खतरनाक है: यह आपके डेटाबेस को सर्वर क्रैश या बिजली की हानि के मामले में डेटा हानि या भ्रष्टाचार के प्रति अधिक संवेदनशील बना देगा। केवल एक विकास मशीन पर इसका उपयोग करें जहां आप क्लस्टर में सभी डेटाबेस की संपूर्ण सामग्री को आसानी से पुनर्स्थापित कर सकते हैं।

MySQL के नोट

संस्करण का समर्थन

Django MySQL 5.6 और उच्चतर का समर्थन करता है।

Django के inspectdb फीचर में inspectdb डेटाबेस का उपयोग किया गया है, जिसमें सभी डेटाबेस स्कीमा पर विस्तृत डेटा है।

Django डेटाबेस को यूनिकोड (UTF-8 एन्कोडिंग) का समर्थन करने की उम्मीद करता है और इसे लेनदेन और संदर्भात्मक अखंडता को लागू करने का कार्य सौंपता है। इस तथ्य से अवगत होना महत्वपूर्ण है कि दो बाद वाले को वास्तव में MySQL द्वारा लागू नहीं किया जाता है जब MyISAM भंडारण इंजन का उपयोग करते हैं, तो अगला भाग देखें।

भंडारण इंजन

MySQL में कई स्टोरेज इंजन हैं । आप सर्वर कॉन्फ़िगरेशन में डिफ़ॉल्ट भंडारण इंजन को बदल सकते हैं।

MySQL का डिफॉल्ट स्टोरेज इंजन InnoDB । यह इंजन पूरी तरह से लेन-देन करने वाला है और विदेशी प्रमुख संदर्भों का समर्थन करता है। यह अनुशंसित विकल्प है। हालाँकि, InnoDB autoincrement काउंटर एक MySQL पुनरारंभ पर खो जाता है क्योंकि यह AUTO_INCREMENT मान को याद नहीं रखता है, बजाय इसे "अधिकतम (आईडी) +1" के रूप में पुन: AUTO_INCREMENT । यह AutoField मानों के अनजाने पुन: उपयोग के परिणामस्वरूप हो सकता है।

MyISAM की मुख्य कमियां यह हैं कि यह लेनदेन का समर्थन नहीं करता है या विदेशी-प्रमुख बाधाओं को लागू नहीं करता है।

MySQL DB API ड्राइवर

MySQL में कुछ ड्राइवर हैं जो PEP 249 में वर्णित पायथन डेटाबेस एपीआई को लागू करते हैं:

  • mysqlclient एक देशी ड्राइवर है। यह अनुशंसित विकल्प है
  • MySQL कनेक्टर / पायथन ओरेकल का एक शुद्ध पायथन चालक है जिसे मानक लाइब्रेरी के बाहर MySQL क्लाइंट लाइब्रेरी या किसी पायथन मॉड्यूल की आवश्यकता नहीं होती है।

ये ड्राइवर थ्रेड-सुरक्षित हैं और कनेक्शन पूलिंग प्रदान करते हैं।

DB API ड्राइवर के अलावा, Django को अपने ORM से डेटाबेस ड्राइवरों तक पहुंचने के लिए एक एडाप्टर की आवश्यकता होती है। Django mysqlclient के लिए एक एडेप्टर प्रदान करता है जबकि MySQL कनेक्टर / पायथन में अपना स्वयं का शामिल है।

mysqlclient

Django को mysqlclient 1.3.7 या बाद के संस्करण की आवश्यकता है।

MySQL कनेक्टर / पायथन

MySQL कनेक्टर / पायथन डाउनलोड पेज से उपलब्ध है। Django एडॉप्टर 1.1.X और बाद के संस्करणों में उपलब्ध है। यह Django के सबसे हालिया रिलीज का समर्थन नहीं कर सकता है।

समय क्षेत्र परिभाषाएँ

यदि आप Django के mysql_tzinfo_to_sql समर्थन का उपयोग करने की योजना बनाते हैं, तो MySQL डेटाबेस में टाइम ज़ोन तालिकाओं को लोड करने के लिए mysql_tzinfo_to_sql का उपयोग करें। यह डेटाबेस के अनुसार आपके MySQL सर्वर के लिए सिर्फ एक बार किया जाना चाहिए।

अपना डेटाबेस बनाना

आप कमांड-लाइन टूल्स और इस एसक्यूएल का उपयोग करके अपना डेटाबेस बना सकते हैं :

CREATE DATABASE <dbname> CHARACTER SET utf8;

यह सुनिश्चित करता है कि सभी टेबल और कॉलम डिफ़ॉल्ट रूप से UTF-8 का उपयोग करेंगे।

कोलाज सेटिंग्स

स्तंभ के लिए टकराने की सेटिंग उस क्रम को नियंत्रित करती है जिसमें डेटा को क्रमबद्ध किया जाता है और साथ ही साथ तार की तुलना भी की जाती है। यह एक डेटाबेस-वाइड स्तर और प्रति-तालिका और प्रति-स्तंभ पर भी सेट किया जा सकता है। यह MySQL प्रलेखन में अच्छी तरह से प्रलेखित है। सभी मामलों में, आप सीधे डेटाबेस तालिकाओं में हेरफेर करके कोलाज सेट करते हैं; Django मॉडल परिभाषा पर इसे सेट करने का एक तरीका प्रदान नहीं करता है।

डिफ़ॉल्ट रूप से, UTF-8 डेटाबेस के साथ, MySQL utf8_general_ci collation का उपयोग करेगा। इसके परिणामस्वरूप केस-असंवेदनशील तरीके से सभी स्ट्रिंग समानता की तुलना की जाती है। यही है, "Fred" और "freD" डेटाबेस स्तर पर समान माना जाता है। यदि आपके पास एक फ़ील्ड पर एक अद्वितीय बाधा है, तो "AA" और "AA" को एक ही कॉलम में डालने का प्रयास करना अवैध होगा, क्योंकि वे डिफ़ॉल्ट टकराव के साथ बराबर (और इसलिए, गैर-अद्वितीय) की तुलना करते हैं। यदि आप किसी विशेष स्तंभ या तालिका पर केस-संवेदी तुलना चाहते हैं, तो utf8_bin collation का उपयोग करने के लिए स्तंभ या तालिका बदलें।

कृपया ध्यान दें कि MySQL यूनिकोड कैरेक्टर सेट्स के अनुसार, utf8_general_ci कोलेशन के लिए तुलनाएं तेज़ हैं, लेकिन utf8_unicode_ci तुलना में थोड़ी कम सही हैं। यदि यह आपके आवेदन के लिए स्वीकार्य है, तो आपको utf8_general_ci उपयोग करना चाहिए क्योंकि यह तेज है। यदि यह स्वीकार्य नहीं है (उदाहरण के लिए, यदि आपको जर्मन शब्दकोश आदेश की आवश्यकता है), तो utf8_unicode_ci उपयोग करें क्योंकि यह अधिक सटीक है।

चेतावनी

मॉडल फॉर्मेट्स अद्वितीय क्षेत्रों को केस-संवेदी तरीके से मान्य करते हैं। इस प्रकार जब केस-असंवेदनशील टकराव का उपयोग किया जाता है, तो अद्वितीय फ़ील्ड मानों वाला एक फॉर्मेट जो केवल मामले से भिन्न होता है, सत्यापन पारित करेगा, लेकिन कॉलिंग save() , एक IntegrityError को उठाया जाएगा।

डेटाबेस से कनेक्ट करना

सेटिंग्स प्रलेखन का संदर्भ लें।

इस क्रम में कनेक्शन सेटिंग्स का उपयोग किया जाता है:

  1. OPTIONS
  2. NAME , USER , PASSWORD , HOST , PORT
  3. MySQL विकल्प फ़ाइलें।

दूसरे शब्दों में, यदि आप OPTIONS में डेटाबेस का नाम सेट करते हैं, तो यह NAME पर पूर्वता लेगा, जो MySQL विकल्प फ़ाइल में कुछ भी ओवरराइड करेगा।

यहाँ एक नमूना विन्यास है जो MySQL विकल्प फ़ाइल का उपयोग करता है:

# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {
            'read_default_file': '/path/to/my.cnf',
        },
    }
}


# my.cnf
[client]
database = NAME
user = USER
password = PASSWORD
default-character-set = utf8

कई अन्य MySQLdb कनेक्शन विकल्प उपयोगी हो सकते हैं, जैसे ssl , init_command , और sql_mode

sql_mode सेट करना

MySQL 5.7 से और MySQL 5.6 के नए STRICT_TRANS_TABLES , sql_mode विकल्प के डिफ़ॉल्ट मान में STRICT_TRANS_TABLES । जब डेटा प्रविष्टि पर छंटनी की जाती है, तो यह विकल्प त्रुटियों में चेतावनी को STRICT_TRANS_TABLES , इसलिए Django अत्यधिक डेटा हानि ( STRICT_TRANS_TABLES या STRICT_ALL_TABLES ) को रोकने के लिए MySQL के लिए एक सख्त मोड को सक्रिय करने की सिफारिश करता है।

यदि आपको SQL मोड को कस्टमाइज़ करने की आवश्यकता है, तो आप अन्य MySQL विकल्पों की तरह sql_mode चर सेट कर सकते हैं: या तो एक कॉन्फ़िगर फ़ाइल में या प्रविष्टि 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'" आपके डेटाबेस कॉन्फ़िगरेशन के OPTIONS भाग में। DATABASES

अलगाव का स्तर

समवर्ती भार चलाते समय, विभिन्न सत्रों से डेटाबेस लेनदेन (कहते हैं, अलग-अलग अनुरोधों को संभालने वाले अलग-अलग धागे) एक दूसरे के साथ बातचीत कर सकते हैं। ये इंटरैक्शन प्रत्येक सत्र के लेन-देन अलगाव स्तर से प्रभावित होते हैं। आप DATABASES में अपने डेटाबेस कॉन्फ़िगरेशन के OPTIONS भाग में 'isolation_level' प्रविष्टि के साथ कनेक्शन का आइसोलेशन स्तर सेट कर सकते हैं। इस प्रविष्टि के लिए मान्य मान चार मानक अलगाव स्तर हैं:

  • 'read uncommitted'
  • 'read committed'
  • 'repeatable read'
  • 'serializable'

या सर्वर के कॉन्फ़िगर आइसोलेशन स्तर का उपयोग करने के लिए None । हालांकि, Django MySQL के डिफ़ॉल्ट, बार-बार पढ़ने के बजाय प्रतिबद्ध पढ़ने के लिए सबसे अच्छा और डिफ़ॉल्ट रूप से काम करता है। बार-बार पढ़ने के साथ डेटा हानि संभव है।

Django 2.0 में बदला:

पुराने संस्करणों में, MySQL डेटाबेस डेटाबेस के आइसोलेशन स्तर (जो बार-बार पढ़ने के लिए चूक करता है) को पढ़ने के बजाय डिफॉल्ट करता है।

अपनी टेबल बनाना

जब Django स्कीमा उत्पन्न करता है, तो यह स्टोरेज इंजन निर्दिष्ट नहीं करता है, इसलिए आपके डेटाबेस सर्वर के लिए जो भी डिफ़ॉल्ट स्टोरेज इंजन है, उसके साथ तालिकाओं का निर्माण किया जाएगा। सबसे आसान उपाय यह है कि आप अपने डेटाबेस सर्वर के डिफॉल्ट स्टोरेज इंजन को वांछित इंजन में सेट करें।

यदि आप एक होस्टिंग सेवा का उपयोग कर रहे हैं और अपने सर्वर के डिफ़ॉल्ट भंडारण इंजन को बदल नहीं सकते हैं, तो आपके पास कुछ विकल्प हैं।

  • तालिकाएँ बनाए जाने के बाद, तालिका को नए स्टोरेज इंजन (जैसे InnoDB) में बदलने के लिए ALTER TABLE स्टेटमेंट निष्पादित करें:

    ALTER TABLE <tablename> ENGINE=INNODB;
    

    यह थकाऊ हो सकता है अगर आपके पास बहुत सारी टेबल हैं।

  • एक अन्य विकल्प init_command लिए init_command विकल्प का उपयोग करने से पहले अपनी टेबल बनाने के लिए है:

    'OPTIONS': {
       'init_command': 'SET default_storage_engine=INNODB',
    }
    

    यह डेटाबेस से कनेक्ट होने पर डिफ़ॉल्ट स्टोरेज इंजन सेट करता है। आपकी तालिकाएँ बनाने के बाद, आपको इस विकल्प को हटा देना चाहिए क्योंकि यह एक क्वेरी जोड़ता है जो प्रत्येक डेटाबेस कनेक्शन के लिए तालिका निर्माण के दौरान आवश्यक है।

टेबल के नाम

MySQL के नवीनतम संस्करणों में भी ज्ञात समस्याएं हैं जो कुछ स्थितियों के तहत कुछ SQL कथन निष्पादित किए जाने पर तालिका नाम के मामले को बदल सकती हैं। यह अनुशंसा की जाती है कि आप इस व्यवहार से उत्पन्न होने वाली किसी भी समस्या से बचने के लिए यदि संभव हो तो लोअरकेस तालिका नामों का उपयोग करें। Django मॉडल से ऑटो नामों को उत्पन्न करते समय लोअरकेस तालिका नामों का उपयोग करता है, इसलिए यह मुख्य रूप से एक विचार है यदि आप db_table पैरामीटर के माध्यम से तालिका नाम को ओवरराइड कर रहे हैं।

Savepoints

Django ORM और MySQL (जब InnoDB स्टोरेज इंजन का उपयोग कर रहा है) दोनों डेटाबेस savepoints सपोर्ट करते हैं।

यदि आप MyISAM संग्रहण इंजन का उपयोग करते हैं, तो कृपया इस तथ्य से अवगत रहें कि यदि आप savepoints के savepoints उपयोग करने का प्रयास करते हैं तो आपको डेटाबेस-जनरेट की गई त्रुटियाँ प्राप्त होंगी। इसका कारण यह है कि एक MySQL डेटाबेस / टेबल के स्टोरेज इंजन का पता लगाना एक महंगा ऑपरेशन है, इसलिए यह निर्णय लिया गया कि इस तरह के डिटेक्शन के परिणामों में इन तरीकों को नो-ऑप के आधार पर गतिशील रूप से परिवर्तित करने के लायक नहीं है।

विशिष्ट क्षेत्रों पर नोट्स

चरित्र क्षेत्र

कोई भी फ़ील्ड जो VARCHAR स्तंभ प्रकारों के साथ संग्रहीत होती है, उनका max_length 255 वर्णों तक सीमित होता है यदि आप फ़ील्ड के लिए unique=True का उपयोग कर रहे हैं। यह CharField , CharField प्रभावित करता है।

TextField सीमाएँ

MySQL एक BLOB या TEXT कॉलम के केवल पहले N वर्णों को अनुक्रमित कर सकता है। चूंकि TextField में एक निर्धारित लंबाई नहीं है, आप इसे unique=True रूप में चिह्नित नहीं कर सकते। MySQL की रिपोर्ट होगी: "BLOB / TEXT कॉलम '<db_column>' का उपयोग बिना मुख्य लंबाई के मुख्य विनिर्देश में किया गया है।"

समय और दिनांक समय क्षेत्रों के लिए आंशिक सेकंड समर्थन

MySQL 5.6.4 और बाद में आंशिक सेकंड स्टोर कर सकता है, बशर्ते कि स्तंभ परिभाषा में एक आंशिक संकेत (जैसे DATETIME(6) ) शामिल हो। पहले के संस्करण उनका बिल्कुल समर्थन नहीं करते हैं।

यदि डेटाबेस सर्वर इसका समर्थन करता है, तो Django, आंशिक कॉलम को शामिल करने के लिए मौजूदा कॉलम को अपग्रेड नहीं करेगा। यदि आप उन्हें किसी मौजूदा डेटाबेस पर सक्षम करना चाहते हैं, तो कमांड कमांड निष्पादित करके, लक्ष्य डेटाबेस पर कॉलम को मैन्युअल रूप से अपडेट करना आपके लिए है:

ALTER TABLE `your_table` MODIFY `your_datetime_column` DATETIME(6)

या डेटा माइग्रेशन में RunSQL ऑपरेशन का उपयोग करना।

TIMESTAMP कॉलम

यदि आप एक विरासत डेटाबेस का उपयोग कर रहे हैं जिसमें TIMESTAMP कॉलम हैं, तो आपको डेटा भ्रष्टाचार से बचने के लिए USE_TZ सेट करना होगा। inspectdb स्तंभ इन कॉलमों को DateTimeField मैप करता है और यदि आप inspectdb समर्थन को सक्षम करते हैं, तो MySQL और Django दोनों यूटीसी से मूल्यों को स्थानीय समय में बदलने का प्रयास करेंगे।

QuerySet.select_for_update() साथ पंक्ति लॉकिंग

MySQL, SELECT ... FOR UPDATE स्टेटमेंट के SELECT ... FOR UPDATE NOWAIT , SKIP LOCKED NOWAIT , और OF विकल्पों का समर्थन नहीं करता है। यदि select_for_update() का उपयोग अभी के साथ किया जाता है nowait=True , skip_locked=True , या फिर NotSupportedError को उठाया जाता है।

स्वचालित टाइपकास्टिंग अप्रत्याशित परिणाम दे सकती है

स्ट्रिंग प्रकार पर एक क्वेरी करते समय, लेकिन पूर्णांक मान के साथ, MySQL तुलना करने से पहले तालिका में सभी मानों के प्रकारों को एक पूर्णांक तक ले जाएगा। यदि आपकी तालिका में 'abc' , 'def' मान शामिल हैं और आप WHERE mycolumn=0 , दोनों पंक्तियों का मिलान होगा। इसी प्रकार, WHERE mycolumn=1 मान 'abc1' से मेल खाएगा। इसलिए, Django में शामिल स्ट्रिंग प्रकार फ़ील्ड हमेशा क्वेरी में उपयोग करने से पहले एक स्ट्रिंग को मान देगा।

यदि आप कस्टम मॉडल फ़ील्ड लागू करते हैं जो सीधे Field से प्राप्त होती हैं, तो get_prep_value() , या RawSQL , extra() , या raw() उपयोग करते RawSQL ओवरराइड कर रहे हैं, तो आपको यह सुनिश्चित करना चाहिए कि आप उपयुक्त टाइपकास्टिंग करें।

SQLite नोट

Django SQLite 3.7.15 और बाद में सपोर्ट करता है।

SQLite उन अनुप्रयोगों के लिए एक उत्कृष्ट विकास विकल्प प्रदान करता है जो मुख्य रूप से केवल-पढ़ने के लिए या छोटे इंस्टॉलेशन पदचिह्न की आवश्यकता होती है। हालाँकि, सभी डेटाबेस सर्वरों के साथ, कुछ अंतर हैं जो SQLite के लिए विशिष्ट हैं, जिनके बारे में आपको जानकारी होनी चाहिए।

पदार्थ मिलान और मामले की संवेदनशीलता

सभी SQLite संस्करणों के लिए, कुछ प्रकार के तारों का मिलान करने का प्रयास करते समय थोड़ा सा सहज ज्ञान युक्त व्यवहार होता है। इसका उपयोग तब किया जाता है जब iexact का उपयोग किया iexact या contains iexact contains फ़िल्टर होते हैं। व्यवहार दो मामलों में विभाजित होता है:

1. मिलान के विकल्प के लिए, सभी मैच केस-असंवेदनशील तरीके से किए जाते हैं। यह एक फ़िल्टर है जैसे कि filter(name__contains="aa") "Aabb" नाम से मेल "Aabb"

2. ASCII रेंज के बाहर के वर्ण वाले स्ट्रिंग्स के लिए, सभी सटीक स्ट्रिंग मिलान केस-संवेदी रूप से किए जाते हैं, तब भी जब केस-असंवेदनशील विकल्प क्वेरी में पास हो जाते हैं। तो iexact फ़िल्टर इन मामलों में exact फ़िल्टर के समान व्यवहार करेगा।

इसके लिए कुछ संभावित वर्कआर्ड को sqlite.org पर प्रलेखित किया गया है , लेकिन वे Django में डिफ़ॉल्ट SQLite बैकएंड द्वारा उपयोग नहीं किए जाते हैं, क्योंकि उन्हें शामिल करना मजबूत रूप से करना काफी मुश्किल होगा। इस प्रकार, Django डिफ़ॉल्ट SQLite व्यवहार को उजागर करता है और केस-असंवेदनशील या विकल्प फ़िल्टरिंग करते समय आपको इसके बारे में पता होना चाहिए।

"डेटाबेस लॉक है" त्रुटियां

SQLite एक हल्के डेटाबेस के रूप में होता है, और इस प्रकार यह उच्च स्तर की संगामिति का समर्थन नहीं कर सकता है। OperationalError: database is locked त्रुटियों से संकेत मिलता है कि आपके एप्लिकेशन को डिफ़ॉल्ट रूप से हैंडल करने में sqlite तुलना में अधिक संगामिति का अनुभव हो रहा है। इस त्रुटि का अर्थ है कि एक थ्रेड या प्रक्रिया में डेटाबेस कनेक्शन पर एक विशेष लॉक होता है और दूसरा थ्रेड लॉक होने की प्रतीक्षा में समयबद्ध होता है।

पायथन के SQLite रैपर में एक डिफ़ॉल्ट टाइमआउट मान होता है जो यह निर्धारित करता है कि कब तक दूसरा थ्रेड लॉक होने से पहले प्रतीक्षा करने के लिए अनुमति देता है और ऑपरेशनलएयर उठाता है OperationalError: database is locked त्रुटि है।

यदि आपको यह त्रुटि मिल रही है, तो आप इसे हल कर सकते हैं:

  • किसी अन्य डेटाबेस बैकएंड पर स्विच करना। एक निश्चित बिंदु पर SQLite वास्तविक दुनिया अनुप्रयोगों के लिए बहुत "लाइट" हो जाता है, और इन प्रकार की संगणक त्रुटियां इंगित करती हैं कि आप उस बिंदु पर पहुंच गए हैं।
  • अपने कोड को संक्षिप्तता को कम करने और यह सुनिश्चित करने के लिए कि डेटाबेस लेनदेन अल्पकालिक हैं।
  • timeout डेटाबेस विकल्प सेट करके डिफ़ॉल्ट टाइमआउट मान बढ़ाएँ:

    'OPTIONS': {
        # ...
        'timeout': 20,
        # ...
    }
    

    यह "डेटाबेस लॉक है" त्रुटियों को फेंकने से पहले SQLite बस थोड़ी देर इंतजार करेगा; यह वास्तव में उन्हें हल करने के लिए कुछ भी नहीं करेगा।

QuerySet.select_for_update() समर्थित नहीं है

SQLite SELECT ... FOR UPDATE सिंटैक्स के SELECT ... FOR UPDATE समर्थन नहीं करता है। इसे कॉल करने से कोई प्रभाव नहीं पड़ेगा।

कच्चे प्रश्नों में "pyformat" पैरामीटर शैली समर्थित नहीं है

अधिकांश बैकएंड के लिए, कच्चे क्वेरीज़ ( Manager.raw() या cursor.execute() ) "pyformat" पैरामीटर शैली का उपयोग कर सकते हैं, जहाँ क्वेरी में प्लेसहोल्डर को '%(name)s' रूप में दिया जाता है और पैरामीटर को पास कर दिया जाता है। एक सूची के बजाय शब्दकोश। SQLite इसका समर्थन नहीं करता है।

ओरेकल नोट

Django Oracle डेटाबेस सर्वर संस्करणों 12.1 और उच्चतर का समर्थन करता है। संस्करण 5.2 या उससे अधिक cx_Oracle पायथन ड्राइवर की आवश्यकता है।

python manage.py migrate काम करने के python manage.py migrate कमांड को python manage.py migrate करने के लिए, आपके Oracle डेटाबेस उपयोगकर्ता के पास निम्न कमांड चलाने के लिए विशेषाधिकार होना चाहिए:

  • तालिका बनाएं
  • सृजन की सीमा
  • बनाने की प्रक्रिया
  • निर्माता बनाएँ

प्रोजेक्ट का परीक्षण सूट चलाने के लिए, उपयोगकर्ता को आमतौर पर इन अतिरिक्त विशेषाधिकारों की आवश्यकता होती है:

  • उपयोगकर्ता बनाइये
  • उपयोगकर्ता का उपयोग करें
  • ड्रॉप उपयोगकर्ता
  • रचनाएँ बनाएँ
  • ड्रॉप टेबल
  • ADMIN OPTION के साथ सेशन बनाएं
  • ADMIN OPTION के साथ बनाएँ
  • ADMIN OPTION के साथ सृजन करें
  • व्यवस्थापक विकल्प के साथ प्रक्रिया बनाएँ
  • व्यवस्थापक विकल्प के साथ निर्माता बनाएँ

जबकि RESOURCE भूमिका के लिए आवश्यक CREATE TABLE , CREATE SEQUENCE की आवश्यकता, CREATE PROCEDURE , और CREATE TRIGGER विशेषाधिकार है, और RESOURCE WITH ADMIN OPTION प्राप्त करने वाला उपयोगकर्ता परिणाम प्रदान कर सकता है, ऐसा उपयोगकर्ता व्यक्तिगत विशेषाधिकार (जैसे CREATE TABLE ) प्रदान नहीं कर सकता है, और इस तरह से सुरक्षित है। RESOURCE WITH ADMIN OPTION आम तौर पर परीक्षण चलाने के लिए पर्याप्त नहीं है।

कुछ परीक्षण सूट भी दृश्य बनाते हैं; इन्हें चलाने के लिए, उपयोगकर्ता को CREATE VIEW WITH ADMIN OPTION विशेषाधिकार के CREATE VIEW WITH ADMIN OPTION भी चाहिए। विशेष रूप से, यह Django के अपने परीक्षण सूट के लिए आवश्यक है।

ये सभी विशेषाधिकार डीबीए की भूमिका में शामिल हैं, जो एक निजी डेवलपर के डेटाबेस पर उपयोग के लिए उपयुक्त है।

Oracle डेटाबेस बैकएंड SYS.DBMS_LOB और SYS.DBMS_RANDOM पैकेज का उपयोग करता है, इसलिए आपके उपयोगकर्ता को इस पर निष्पादन अनुमति की आवश्यकता होगी। यह सामान्य रूप से डिफ़ॉल्ट रूप से सभी उपयोगकर्ताओं के लिए सुलभ है, लेकिन यदि ऐसा नहीं है, तो आपको इस तरह की अनुमति देने की आवश्यकता होगी:

GRANT EXECUTE ON SYS.DBMS_LOB TO user;
GRANT EXECUTE ON SYS.DBMS_RANDOM TO user;

डेटाबेस से कनेक्ट करना

अपने ओरेकल डेटाबेस के सेवा नाम का उपयोग करने के लिए, आपकी settings.py फ़ाइल को कुछ इस तरह दिखना चाहिए:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'xe',
        'USER': 'a_user',
        'PASSWORD': 'a_password',
        'HOST': '',
        'PORT': '',
    }
}

इस स्थिति में, आपको HOST और PORT दोनों को खाली छोड़ देना चाहिए। हालाँकि, यदि आप tnsnames.ora फ़ाइल या समान नामकरण विधि का उपयोग नहीं करते हैं और इस उदाहरण में SID ("xe") का उपयोग करके कनेक्ट करना चाहते हैं, तो HOST और PORT दोनों को भरें:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'xe',
        'USER': 'a_user',
        'PASSWORD': 'a_password',
        'HOST': 'dbprod01ned.mycompany.com',
        'PORT': '1540',
    }
}

आपको या तो HOST और PORT दोनों की आपूर्ति करनी चाहिए, या दोनों को खाली स्ट्रिंग के रूप में छोड़ना चाहिए। Django उस पसंद के आधार पर एक अलग कनेक्ट डिस्क्रिप्टर का उपयोग करेगा।

पिरोया विकल्प

यदि आप Django को एक बहुस्तरीय वातावरण में चलाने की योजना बनाते हैं (जैसे किसी भी आधुनिक ऑपरेटिंग सिस्टम पर डिफ़ॉल्ट MPM मॉड्यूल का उपयोग करके Apache), तो आपको अपने Oracle डेटाबेस कॉन्फ़िगरेशन के True विकल्प को True सेट करना होगा :

'OPTIONS': {
    'threaded': True,
},

ऐसा करने में विफलता के परिणामस्वरूप क्रैश और अन्य विषम व्यवहार हो सकते हैं।

INSERT ... पुनर्मूल्यांकन में

डिफ़ॉल्ट रूप से, ओरेकल बैकएंड नई पंक्तियों को सम्मिलित करते समय एक AutoField के मान को कुशलतापूर्वक प्राप्त करने के लिए एक RETURNING INTO क्लॉज का उपयोग करता है। इस व्यवहार के परिणामस्वरूप कुछ असामान्य सेटअपों में डेटाबेसइर्र हो सकता है, जैसे कि दूरस्थ तालिका में सम्मिलित करते समय, या ट्रिगर के INSTEAD OF साथ दृश्य INSTEAD OF । डेटाबेस कॉन्फ़िगरेशन के उपयोग के लिए False विकल्प सेट करके use_returning_into : RETURNING INTO खंड को निष्क्रिय किया जा सकता है:

'OPTIONS': {
    'use_returning_into': False,
},

इस स्थिति में, Oracle बैकएंड AutoField मानों को पुनः प्राप्त करने के लिए एक अलग SELECT क्वेरी का उपयोग करेगा।

नामकरण के मुद्दे

ओरेकल 30 अक्षरों की एक नाम लंबाई सीमा लगाता है। इसे समायोजित करने के लिए, बैकएंड डेटाबेस पहचानकर्ताओं को फिट करने के लिए ट्रंकुकेट करता है, जो कि पुन: प्रयोज्य एमडी 5 हैश मान के साथ काटे गए नाम के अंतिम चार वर्णों को प्रतिस्थापित करता है। इसके अतिरिक्त, बैकएंड डेटाबेस पहचानकर्ताओं को सभी अपरकेस में बदल देता है।

इन परिवर्तनों को रोकने के लिए (यह आमतौर पर केवल तब आवश्यक होता है जब विरासत डेटाबेस से निपटने या अन्य उपयोगकर्ताओं से संबंधित तालिकाओं तक पहुँचने के लिए), db_table के मान के रूप में एक उद्धृत नाम का उपयोग करें:

class LegacyModel(models.Model):
    class Meta:
        db_table = '"name_left_in_lowercase"'

class ForeignModel(models.Model):
    class Meta:
        db_table = '"OTHER_USER"."NAME_ONLY_SEEMS_OVER_30"'

उद्धृत नाम का उपयोग Django के अन्य समर्थित डेटाबेस बैकएंड के साथ भी किया जा सकता है; ओरेकल को छोड़कर, हालांकि, उद्धरणों का कोई प्रभाव नहीं है।

migrate चलाते समय, एक ORA-06552 त्रुटि का सामना करना पड़ सकता है यदि कुछ ओरेकल कीवर्ड का उपयोग किसी मॉडल फ़ील्ड के नाम या db_column विकल्प के मान के रूप में किया जाता है। Django अधिकांश ऐसी समस्याओं को रोकने के लिए प्रश्नों में उपयोग किए गए सभी पहचानकर्ताओं को उद्धृत करता है, लेकिन यह त्रुटि तब भी हो सकती है जब एक Oracle नाम एक कॉलम नाम के रूप में उपयोग किया जाता है। विशेष रूप से, नाम, timestamp , number या float को फ़ील्ड नाम के रूप में उपयोग करने से बचने के लिए ध्यान रखें।

खाली और खाली तार

Django आमतौर पर NULL बजाय खाली स्ट्रिंग ( '' ) का उपयोग करना पसंद करता है, लेकिन Oracle दोनों को पहचानता है। इसके चारों ओर पाने के लिए, ओरेकल बैकएंड उन फ़ील्ड्स पर एक स्पष्ट null विकल्प को अनदेखा करता है जिनके पास संभव मान के रूप में खाली स्ट्रिंग है और डीडीएल को उत्पन्न करता है जैसे कि null=True । डेटाबेस से लाते समय, यह माना जाता है कि इनमें से किसी एक क्षेत्र में एक NULL मान का अर्थ वास्तव में खाली स्ट्रिंग है, और डेटा इस धारणा को प्रतिबिंबित करने के लिए चुपचाप परिवर्तित हो जाता है।

TextField सीमाएँ

ओरेकल बैकएंड NCLOB को NCLOB कॉलम के रूप में NCLOB है। सामान्य रूप से ऐसे LOB कॉलम के उपयोग पर Oracle कुछ सीमाएँ लगाता है:

  • LOB कॉलम प्राथमिक कुंजी के रूप में उपयोग नहीं किया जा सकता है।
  • LOB कॉलम इंडेक्स में उपयोग नहीं किए जा सकते हैं।
  • LOB कॉलम का SELECT DISTINCT सूची में नहीं किया जा सकता है। इसका मतलब यह है कि TextField कॉलम को शामिल करने वाले मॉडल पर QuerySet.distinct विधि का उपयोग करने का प्रयास QuerySet.distinct त्रुटि के परिणामस्वरूप होगा, जो ओरेकल के खिलाफ चलता है। वर्कअराउंड के रूप में, TextField कॉलम को SELECT DISTINCT सूची में शामिल करने से रोकने के लिए distinct() के साथ संयोजन में QuerySet.defer विधि का उपयोग SELECT DISTINCT

3-पार्टी डेटाबेस बैकएंड का उपयोग करना

आधिकारिक तौर पर समर्थित डेटाबेस के अलावा, 3 पार्टियों द्वारा प्रदान किए गए बैकएंड हैं जो आपको Django के साथ अन्य डेटाबेस का उपयोग करने की अनुमति देते हैं:

इन अनौपचारिक बैकेंड द्वारा समर्थित Django संस्करण और ORM सुविधाएँ काफी भिन्न होती हैं। किसी भी समर्थन प्रश्नों के साथ, इन अनौपचारिक बैकएंड की विशिष्ट क्षमताओं के बारे में प्रश्न, प्रत्येक तीसरे चरण के प्रोजेक्ट द्वारा प्रदान किए गए समर्थन चैनलों को निर्देशित किया जाना चाहिए।

Original text