मुझे इस समस्या का भी सामना करना पड़ा जब मैं एक तालिका में डेटा आयात करने के लिए ASCII डेटा फ़ाइलों को पार्स कर रहा था। समस्या यह है कि मैं सहजतापूर्वक और सहजता से एसक्यूएलकेमी को अद्वितीय डेटा की अनुमति देते हुए डुप्लिकेट पंक्तियों को छोड़ना चाहता था। या यह मामला हो सकता है कि वर्तमान SQL इंजन के कारण एक यादृच्छिक त्रुटि को पंक्ति के साथ फेंक दिया जाता है, जैसे यूनिकोड तारों की अनुमति नहीं है।
हालांकि, यह व्यवहार SQL इंटरफ़ेस की परिभाषा के दायरे से बाहर है। एसक्यूएल एपीआई, और इसलिए SQLAlchemy केवल लेनदेन को समझता है और करता है, और इस चुनिंदा व्यवहार के लिए खाता नहीं है। इसके अलावा, यह autocommit सुविधा पर निर्भर होने के लिए खतरनाक लगता है, क्योंकि सम्मिलन के बाद प्रविष्टि रोकता है, शेष डेटा छोड़ देता है।
मेरा समाधान (जो मुझे यकीन नहीं है कि यह सबसे सुंदर है या नहीं) लूप, पकड़ और लॉग अपवादों में प्रत्येक पंक्ति को संसाधित करना और अंत में परिवर्तन करना है।
मान लीजिए कि आपने किसी भी तरह सूचियों की सूची में डेटा हासिल किया है, यानी पंक्तियों की सूची जो स्तंभ मानों की सूचियां हैं। तो फिर तुम एक पाश में प्रत्येक पंक्ति पढ़ें:
# Python 3.5
from sqlalchemy import Table, create_engine
import logging
# Create the engine
# Create the table
# Parse the data file and save data in `rows`
conn = engine.connect()
trans = conn.begin() # Disables autocommit
exceptions = {}
totalRows = 0
importedRows = 0
ins = table.insert()
for currentRowIdx, cols in enumerate(rows):
try:
conn.execute(ins.values(cols)) # try to insert the column values
importedRows += 1
except Exception as e:
exc_name = type(e).__name__ # save the exception name
if not exc_name in exceptions:
exceptions[exc_name] = []
exceptions[exc_name].append(currentRowIdx)
totalRows += 1
for key, val in exceptions.items():
logging.warning("%d out of %d lines were not imported due to %s."%(len(val), totalRows, key))
logging.info("%d rows were imported."%(importedRows))
trans.commit() # Commit at the very end
conn.close()
आदेश में इस ऑपरेशन में गति को अधिकतम करने के लिए, आपको autocommit अक्षम करना चाहिए। मैं SQLite के साथ इस कोड का उपयोग कर रहा हूं और यह अभी भी sqlite3
का उपयोग करके मेरे पुराने संस्करण की तुलना में 3-5 गुना धीमा है, यहां तक कि स्वतः से अक्षम अक्षम भी है। (जिस कारण से मैंने स्क्लाक्लेमी को पोर्ट किया था, वह इसे MySQL के साथ उपयोग करने में सक्षम था।)
यह इस अर्थ में सबसे सुंदर समाधान नहीं है कि यह SQLite के लिए प्रत्यक्ष इंटरफ़ेस जितना तेज़ नहीं है। अगर मैं कोड को प्रोफाइल करता हूं और निकट भविष्य में बाधा पाता हूं, तो मैं इस उत्तर को समाधान के साथ अपडेट कर दूंगा।