2010-07-22 10 views
10

के साथ SQLite डेटाबेस में बाइनरी फ़ाइल डालें, मैं एक साधारण पायथन स्क्रिप्ट लिखने की कोशिश कर रहा हूं जो SQLite डेटाबेस में .odt दस्तावेज़ों को सम्मिलित करता है। यहाँ मैं अब तक क्या किया है, लेकिन यह काम करने के लिए प्रतीत नहीं होता है:पाइथन

f=open('Loremipsum.odt', 'rb') 
k=f.read() 
f.close() 
cursor.execute="INSERT INTO notes (note) VALUES ('%s')" %(sqlite.Binary(k)) 
cursor.close() 
conn.close() 

मैं किसी भी त्रुटि संदेश नहीं मिलता है, लेकिन जहाँ तक मैं देख सकता हूँ रिकॉर्ड डाला जाता है। मैं क्या गलत कर रहा हूं? साथ ही, मैं संग्रहित दस्तावेज़ को वापस कैसे निकाल सकता हूं? धन्यवाद!

उत्तर

28

सुनिश्चित नहीं हैं कि, कि sqlite.Binary आप उपयोग कर रहे हैं, लेकिन, वैसे भी है यहाँ एक काम उदाहरण है:

import sqlite3 

# let's just make an arbitrary binary file... 
with open('/tmp/abin', 'wb') as f: 
    f.write(''.join(chr(i) for i in range(55))) 
# ...and read it back into a blob 
with open('/tmp/abin', 'rb') as f: 
    ablob = f.read() 

# OK, now for the DB part: we make it...: 
db = sqlite3.connect('/tmp/thedb') 
db.execute('CREATE TABLE t (thebin BLOB)') 
db.execute('INSERT INTO t VALUES(?)', [buffer(ablob)]) 
db.commit() 
db.close() 

# ...and read it back: 
db = sqlite3.connect('/tmp/thedb') 
row = db.execute('SELECT * FROM t').fetchone() 
print repr(str(row[0])) 

जब अजगर 2.6 के साथ चलाने के लिए, इस कोड को दिखाता है, उम्मीद और वांछित के रूप में: '\ x00 \ X01 \ X02 \ X03 \ x04 \ X05 \ X06 \ X07 \ x08 \ t \ n \ x0b \ x0c \ r \ x0e \ x0f \ x10 \ X11 \ x12 \ x13 \ x14 \ x15 \ x16 \ x17 \ x18 \ x19 \ x1a \ x1B \ x1c \ x1d \ x1e \ x1f "# $% & \ '() * +, -।/'!

नोट buffer उपयोग करने के लिए ब्लॉब सम्मिलित करने के लिए की जरूरत है, और str इसे पढ़ने के लिए एक स्ट्रिंग के रूप में वापस (क्योंकि यहका उपयोग करता है परिणाम के रूप में 10 प्रकार भी) - यदि आप इसे डिस्क पर लिखने जा रहे हैं तो बाद वाले मार्ग की आवश्यकता नहीं होगी (क्योंकि write फ़ाइलों की विधि बफर ऑब्जेक्ट्स को स्वीकार करती है और साथ ही यह स्ट्रिंग स्वीकार करती है)।

+0

बिल्कुल सही! आपकी मदद के लिए बहुत बहुत धन्यवाद! – dmpop

+0

@ डंपॉप, आपका स्वागत है! –

+0

अच्छा उदाहरण, मेरे पास एक समान प्रश्न है (http://stackoverflow.com/questions/3915888/how-do-i-properly-format-a-stringio-objectpython-and-django-to-be-inserted-into) , अगर आप इसे देख सकते हैं तो मैं बहुत आभारी रहूंगा। –

6

समस्याएं:

  1. पूर्ण कोड है कि आप दौड़ा दिखाई नहीं दिया। आपको sqlite.Binary(k) जैसी चीज़ों का आकलन करने के लिए उत्तरदाताओं को नहीं छोड़ना चाहिए।

  2. मौलिक समस्या: आपने अपना लेनदेन नहीं किया है।conn.close() से पहले उपयोग करें।

6

दिए गए उदाहरण के साथ कई समस्याएं हैं। मैं उन्हें एक-एक करके संबोधित करूंगा।

  • कोई त्रुटि जांच नहीं है। हमें या तो कोशिश करने/छोड़ने/अंत में का निर्माण कीवर्ड के साथ उपयोग करने या उपयोग करने की आवश्यकता है।
  • पायथन विधियां सी # गुणों की तरह नहीं हैं। आप execute() विधि नहीं चला रहे हैं, आप किसी ऑब्जेक्ट को कुछ स्ट्रिंग असाइन कर रहे हैं। (पायथन में, विधियां भी वस्तुएं हैं।)
  • बहुत महत्वपूर्ण यह है कि आपका कोड एसक्यूएल इंजेक्शन हमलों के अधीन है। हमें पायथन स्ट्रिंग ऑपरेशंस का उपयोग करके कभी भी SQL कथन नहीं बनाना चाहिए। हमें हमेशा प्लेसहोल्डर का उपयोग करना चाहिए।
  • उदाहरण अपूर्ण है। जो एक मुश्किल मुद्दा की ओर जाता है। मान लीजिए कि CREATE TABLE कथन था तो एक नया निहित लेनदेन बनाया जाएगा। और डेटा को डेटाबेस फ़ाइल में सहेजने के लिए commit() कथन जारी किया जाना चाहिए। SQLite में, SELECT के अलावा कोई भी बयान एक निहित लेनदेन शुरू करता है। (MySQL जैसे कुछ डेटाबेस डिफ़ॉल्ट रूप से ऑटोकॉमिट मोड में हैं। SQLite के लिए यह सच नहीं है।

    #!/usr/bin/python 
    # -*- coding: utf-8 -*- 
    
    import sqlite3 as lite 
    
    fl = open('book.odt', 'rb') 
    
    with fl: 
        data = fl.read() 
    
    con = lite.connect('test.db') 
    
    with con: 
    
        cur = con.cursor()  
    
        cur.execute("CREATE TABLE IF NOT EXISTS Docs(Data BLOB)") 
    
        sql = "INSERT INTO Docs(Data) VALUES (?)" 
        cur.execute(sql, (lite.Binary(data),)) 
    

    book.odt फ़ाइल वर्तमान कार्यशील निर्देशिका में स्थित है:)

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

+1

'lite' के रूप में' sqlite3' का उपयोग क्यों करें? – Tshepang

+0

यह सिर्फ मेरी शैली है। यह कोड थोड़ा सा छोटा करता है। –

+0

लेकिन आप केवल एक बार इसका इस्तेमाल करते हैं। यह बहुत अजीब है ... मुझे जीत नहीं दिख रही है। यदि हम एक चरित्र गणना करते हैं, तो यह कोड को छोटा नहीं करता है। – Tshepang