SQLite
 sql >> डेटाबेस >  >> RDS >> SQLite

पायथन और SQLite चेतावनी

SQLite एक लोकप्रिय, रिलेशनल डेटाबेस है जिसे आप अपने एप्लिकेशन में एम्बेड करते हैं। पायथन आधिकारिक बाइंडिंग के साथ SQLite के साथ आता है। यह आलेख पायथन में SQLite का उपयोग करने की चेतावनियों की जांच करता है। यह उन समस्याओं को प्रदर्शित करता है जो लिंक किए गए SQLite पुस्तकालयों के विभिन्न संस्करण पैदा कर सकते हैं, कैसे datetime वस्तुओं को ठीक से संग्रहीत नहीं किया जाता है, और पायथन के with connection पर निर्भर करते समय आपको अतिरिक्त सावधानी बरतने की आवश्यकता है आपका डेटा देने के लिए संदर्भ प्रबंधक।

परिचय

SQLite एक लोकप्रिय, रिलेशनल डेटाबेस (DB) सिस्टम है . अपने बड़े, क्लाइंट-सर्वर आधारित भाइयों के विपरीत, जैसे कि MySQL, SQLite को आपके एप्लिकेशन में लाइब्रेरी के रूप में एम्बेड किया जा सकता है . पायथन आधिकारिक तौर पर बाइंडिंग (आधिकारिक डॉक्स) के माध्यम से SQLite का समर्थन करता है। हालांकि, उन बाइंडिंग के साथ काम करना हमेशा सीधा नहीं होता है। सामान्य SQLite चेतावनियों के अलावा, जिन पर मैंने पहले चर्चा की थी, ऐसे कई पायथन-विशिष्ट मुद्दे हैं जिनकी हम इस लेख में जांच करेंगे

परिनियोजन लक्ष्य के साथ संस्करण असंगतताएं

यह काफी सामान्य है कि डेवलपर्स एक मशीन पर कोड बनाते हैं और परीक्षण करते हैं जो ऑपरेटिंग सिस्टम (ओएस) और हार्डवेयर के संदर्भ में कोड को तैनात करने वाले (बहुत) अलग होता है। इससे तीन तरह की समस्याएं होती हैं:

  • एप्लिकेशन OS या हार्डवेयर के अंतर के कारण भिन्न व्यवहार करता है . उदाहरण के लिए, जब लक्ष्य मशीन में आपकी मशीन की तुलना में कम मेमोरी होती है, तो आप प्रदर्शन समस्याओं में भाग सकते हैं। या SQLite दूसरों की तुलना में एक OS पर कुछ संचालन धीमी गति से निष्पादित कर सकता है, क्योंकि इसके द्वारा उपयोग किए जाने वाले अंतर्निहित निम्न-स्तरीय OS API अलग हैं।
  • SQLite संस्करण परिनियोजन लक्ष्य पर डेवलपर मशीन के संस्करण से भिन्न होता है . यह दोनों दिशाओं में समस्याएँ पैदा कर सकता है, क्योंकि समय के साथ नई सुविधाएँ जोड़ी जाती हैं (और व्यवहार में बदलाव), आधिकारिक चैंज देखें। उदाहरण के लिए, एक पुराने तैनात SQLite संस्करण में ऐसी सुविधाओं की कमी हो सकती है जो विकास में ठीक काम करती हैं। साथ ही, परिनियोजन में एक नया SQLite संस्करण आपके विकास मशीन पर आपके द्वारा उपयोग किए जाने वाले पुराने संस्करण से भिन्न व्यवहार कर सकता है, उदा। जब SQLite टीम कुछ डिफ़ॉल्ट मान बदलती है।
  • या तो SQLite की Python बाइंडिंग, या C लाइब्रेरी, पूरी तरह से परिनियोजन लक्ष्य पर अनुपलब्ध हो सकती हैं . यह एक लिनक्स है -वितरण-विशिष्ट समस्या . आधिकारिक Windows और macOS वितरण में एक बंडल होगा SQLite C लाइब्रेरी का संस्करण। लिनक्स पर, SQLite लाइब्रेरी एक अलग पैकेज है। यदि आप स्वयं पायथन संकलित करते हैं, उदा। क्योंकि आप डेबियन/रास्पियन/आदि का उपयोग करते हैं। वितरण जो प्राचीन फीचर संस्करणों के साथ जहाज करता है, पायथन make बिल्ड स्क्रिप्ट केवल पायथन की SQLite बाइंडिंग का निर्माण करेगी अगर पायथन की संकलन प्रक्रिया के दौरान एक स्थापित SQLite C लाइब्रेरी का पता चला था . यदि आप स्वयं पायथन का ऐसा पुन:संकलन करते हैं, तो आपको यह सुनिश्चित करना चाहिए कि स्थापित SQLite C लाइब्रेरी हालिया है . apt . के माध्यम से SQLite स्थापित करते समय यह, फिर से, डेबियन आदि के मामले में नहीं है , इसलिए आपको पूर्व . स्वयं भी SQLite बनाना और स्थापित करना पड़ सकता है पायथन के निर्माण के लिए।

यह पता लगाने के लिए कि आपके पायथन दुभाषिया द्वारा SQLite C लाइब्रेरी के किस संस्करण का उपयोग किया जाता है, इस कमांड को चलाएँ:

python3 -c "import sqlite3; print(sqlite3.sqlite_version)"Code language: Bash (bash)

sqlite3.sqlite_version की जगह sqlite3.version . के साथ आपको पायथन के SQLite बाइंडिंग का संस्करण देगा ।

अंतर्निहित SQLite C लाइब्रेरी को अपडेट करना

यदि आप नवीनतम SQLite संस्करण की सुविधाओं या बग फिक्स से लाभ प्राप्त करना चाहते हैं, तो आप भाग्य में हैं। SQLite C लाइब्रेरी को आमतौर पर रन-टाइम पर लिंक किया जाता है और इस प्रकार इसे आपके इंस्टॉल किए गए पायथन इंटरप्रेटर में बिना किसी बदलाव के बदला जा सकता है। ठोस कदम आपके ओएस पर निर्भर करते हैं (पायथन 3.6+ के लिए परीक्षण किया गया):

1) विंडोज़: SQLite डाउनलोड पृष्ठ से x86 या x64 पूर्व-संकलित बायनेरिज़ डाउनलोड करें और sqlite3.dll को बदलें फ़ाइल DLLs में मिली है आपके पायथन इंस्टॉलेशन का फ़ोल्डर जिसे आपने अभी डाउनलोड किया है।

2) लिनक्स: SQLite डाउनलोड पेज से autoconf प्राप्त करें स्रोत, संग्रह को निकालें, और चलाएं ./configure && make && make install जो पुस्तकालय को /usr/local/lib . में स्थापित करेगा डिफ़ॉल्ट रूप से।
फिर लाइन जोड़ें export LD_LIBRARY_PATH=/usr/local/lib शेल स्क्रिप्ट की शुरुआत में जो आपकी पायथन लिपि शुरू करती है, जो आपके पायथन दुभाषिया को स्वयं निर्मित पुस्तकालय का उपयोग करने के लिए मजबूर करती है।

3) macOS: मेरे विश्लेषण से, ऐसा लगता है कि SQLite C लाइब्रेरी को Python बाइंडिंग . में संकलित किया गया है बाइनरी (_sqlite3.cpython-36m-darwin.so ) यदि आप इसे बदलना चाहते हैं, तो आपको संभवतः अपने स्थापित पायथन इंस्टॉलेशन से मेल खाने वाला पायथन स्रोत कोड प्राप्त करने की आवश्यकता होगी (जैसे 3.7.6 या जो भी संस्करण आप उपयोग करते हैं)। मैकोज़ बिल्ड स्क्रिप्ट का उपयोग करके स्रोत से पायथन संकलित करें। इस स्क्रिप्ट में SQLite की C लाइब्रेरी को डाउनलोड करना और बनाना शामिल है, इसलिए नवीनतम SQLite संस्करण को संदर्भित करने के लिए स्क्रिप्ट को संपादित करना सुनिश्चित करें। अंत में, संकलित बाइंडिंग फ़ाइल का उपयोग करें (उदा. _sqlite3.cpython-37m-darwin.so ), पुराने को बदलने के लिए।

समयक्षेत्र-जागरूक datetime के साथ कार्य करना ऑब्जेक्ट

अधिकांश पायथन डेवलपर आमतौर पर datetime . का उपयोग करते हैं टाइमस्टैम्प के साथ काम करते समय ऑब्जेक्ट। बेवकूफ हैं datetime वस्तुएं जो अपने समय क्षेत्र के बारे में नहीं जानती हैं, और गैर-भोले वे, जो समय क्षेत्र हैं-जागरूक . यह सर्वविदित है कि पायथन का datetime मॉड्यूल विचित्र है, जिससे टाइमज़ोन-जागरूक बनाना भी मुश्किल हो जाता है datetime.datetime वस्तुओं। उदाहरण के लिए, datetime.datetime.utcnow() . पर कॉल करें एक बेवकूफ . बनाता है ऑब्जेक्ट, जो उन डेवलपर्स के लिए प्रति-सहज है जो datetime . में नए हैं एपीआई, पायथन से यूटीसी टाइमज़ोन का उपयोग करने की उम्मीद करते हैं! तीसरे पक्ष के पुस्तकालय, जैसे कि पायथन-डेटुटिल, इस कार्य को सुविधाजनक बनाते हैं। टाइमज़ोन-अवेयर ऑब्जेक्ट बनाने के लिए, आप इस तरह के कोड का उपयोग कर सकते हैं:

from dateutil.tz import tzutc
import datetime
timezone_aware_dt = datetime.datetime.now(tzutc())Code language: Python (python)

दुर्भाग्य से, sqlite3 . का आधिकारिक पायथन प्रलेखन जब टाइमस्टैम्प को संभालने की बात आती है तो मॉड्यूल भ्रामक होता है। जैसा कि यहां बताया गया है, datetime PARSE_DECLTYPES . का उपयोग करते समय ऑब्जेक्ट अपने आप रूपांतरित हो जाते हैं (और एक TIMESTAMP घोषित करना कॉलम)। हालांकि यह तकनीकी रूप से सही है, रूपांतरण खो जाएगा समय क्षेत्र जानकारी ! नतीजतन, यदि आप वास्तव में समय क्षेत्र का उपयोग कर रहे हैं-जागरूक datetime.datetime ऑब्जेक्ट, आपको अपने स्वयं के कन्वर्टर्स पंजीकृत करने होंगे , जो समय क्षेत्र की जानकारी को इस प्रकार बनाए रखता है:

def convert_timestamp_to_tzaware(timestamp: bytes) -> datetime.datetime:
    # sqlite3 provides the timestamp as byte-string
    return dateutil.parser.parse(timestamp.decode("utf-8"))
 
def convert_timestamp_to_sqlite(dt: datetime.datetime) -> str:
    return dt.isoformat()  # includes the timezone information at the end of the string
 
sqlite3.register_converter("timestamp", convert_timestamp_to_tzaware)
sqlite3.register_adapter(datetime.datetime, convert_timestamp_to_sqlite)Code language: Python (python)

जैसा कि आप देख सकते हैं, टाइमस्टैम्प को केवल TEXT . के रूप में संग्रहीत किया जाता है अंततः। SQLite में कोई वास्तविक "तारीख" या "डेटाटाइम" डेटा प्रकार नहीं है।

लेन-देन और ऑटो-प्रतिबद्धता

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

with connection:  # this uses the connection as context manager
    # do something with it, e.g.
    connection.execute("SOME QUERY")Code language: Python (python)

उपरोक्त ब्लॉक से बाहर निकलने के बाद, sqlite3 परोक्ष रूप से कॉल करता है connection.commit() , लेकिन ऐसा केवल तभी करता है जब कोई लेन-देन चल रहा हो . DML (डेटा मॉडिफिकेशन लैंग्वेज) स्टेटमेंट स्वचालित रूप से एक लेनदेन शुरू करते हैं, लेकिन क्वेरी जिसमें DROP शामिल होते हैं या CREATE TABLE / INDEX बयान नहीं हैं, क्योंकि वे दस्तावेज़ीकरण के अनुसार डीएमएल के रूप में नहीं गिने जाते हैं। यह प्रति-सहज है, क्योंकि ये कथन स्पष्ट रूप से डेटा को संशोधित करते हैं।

इस प्रकार, यदि आप कोई DROP चलाते हैं या CREATE TABLE / INDEX संदर्भ प्रबंधक के अंदर बयान, स्पष्ट रूप से एक BEGIN TRANSACTION निष्पादित करना अच्छा अभ्यास है पहले बयान , ताकि संदर्भ प्रबंधक वास्तव में connection.commit() . को कॉल करे आपके लिए।

64-बिट पूर्णांकों का प्रबंधन

पिछले लेख में मैंने पहले ही चर्चा की थी कि SQLite में बड़े पूर्णांक के साथ समस्याएँ हैं जो -2^63 से छोटे हैं , या 2^63 . से अधिक या बराबर . यदि आप उन्हें क्वेरी पैरामीटर में उपयोग करने का प्रयास करते हैं (? . के साथ) सिंबल), पायथन का sqlite3 मॉड्यूल एक OverflowError: Python int too large to convert to SQLite INTEGER , आपको आकस्मिक डेटा हानि से बचाते हुए।

बहुत बड़े पूर्णांकों को ठीक से संभालने के लिए, आपको यह करना होगा:

  1. TEXT का प्रयोग करें संबंधित तालिका कॉलम के लिए टाइप करें, और
  2. नंबर को str में बदलें पहले से ही पायथन में , इसे एक पैरामीटर के रूप में उपयोग करने से पहले।
  3. स्ट्रिंग्स को वापस int में बदलें पायथन में, जब SELECT आईएनजी डेटा

निष्कर्ष

पायथन का आधिकारिक sqlite3 मॉड्यूल SQLite के लिए एक उत्कृष्ट बाध्यकारी है। हालाँकि, SQLite के लिए नए डेवलपर्स को यह समझने की आवश्यकता है कि Python बाइंडिंग और अंतर्निहित SQLite C लाइब्रेरी में अंतर है। SQLite के संस्करण अंतर के कारण, छाया में खतरा है। ये तब भी हो सकते हैं जब आप समान चलाते हैं दो अलग-अलग मशीनों पर पायथन संस्करण, क्योंकि SQLite C लाइब्रेरी अभी भी एक अलग संस्करण का उपयोग कर रही है। मैंने अन्य समस्याओं पर भी चर्चा की जैसे डेटाटाइम ऑब्जेक्ट्स को संभालना और लेनदेन का उपयोग करके लगातार डेटा बदलना। मैं स्वयं उनके बारे में नहीं जानता था, जिससे मेरे अनुप्रयोगों के उपयोगकर्ताओं के लिए डेटा हानि हुई, इसलिए मुझे आशा है कि आप उन्हीं गलतियों से बच सकते हैं जो मैंने की थीं।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQLite में डेटाटाइम कैसे प्रारूपित करें

  2. डेटाबेस से एंड्रॉइड स्क्लाइट ऑनअपग्रेड डिलीट टेबल

  3. SQLite सेल्फ-जॉइन

  4. स्क्लाइट डेटाबेस में उनके नाम के अनुसार ड्रा करने योग्य से छवि कैसे प्राप्त करें और फिर इसे सूची दृश्य में प्रदर्शित करें

  5. एंड्रॉइड में डेटाबेस फ़ाइल से संस्करण संख्या को कैसे पढ़ा जाए जो संपत्ति फ़ोल्डर में रखा गया है