sqlite3.ProgrammingError: আপনি 8-বিট বাইটস্ট্রিংগুলি ব্যবহার করবেন না যতক্ষণ না আপনি এমন একটি টেক্সট_ফ্যাক্টরি ব্যবহার করেন যা 8-বিট বাইটস্ট্রিংগুলি ব্যাখ্যা করতে পারে


90

পাইথনে এসকিউএলাইট 3 ব্যবহার করে, আমি ইউটিএফ -8 এইচটিএমএল কোডের স্নিপেটের সংক্ষেপিত সংস্করণটি সংরক্ষণ করার চেষ্টা করছি।

কোডটি এর মতো দেখাচ্ছে:

...
c = connection.cursor()
c.execute('create table blah (cid integer primary key,html blob)')
...
c.execute('insert or ignore into blah values (?, ?)',(cid, zlib.compress(html)))

কোন পর্যায়ে ত্রুটিটি পান:

sqlite3.ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.

যদি আমি 'ব্লব' এর পরিবর্তে 'টেক্সট' ব্যবহার করি এবং এইচটিএমএল স্নিপেটটি সংকুচিত না করি তবে এটি সমস্ত সূক্ষ্মভাবে কাজ করে (ডিবি যদিও বড় হয়)। আমি যখন পাইথন জেলিব লাইব্রেরির মাধ্যমে 'ব্লব' ব্যবহার করি এবং সংক্ষেপ করি তখন আমি উপরের ত্রুটি বার্তাটি পাই। আমি চারপাশে তাকালাম কিন্তু এইটির জন্য একটি সহজ উত্তর খুঁজে পাইনি।

উত্তর:


94

আপনি যদি sqlite3 এ ইউনিকোড স্ট্রিংয়ের পরিবর্তে 8-বিট স্ট্রিং ব্যবহার করতে চান তবে স্ক্লাইট সংযোগের জন্য অ্যাপোপ্রটিট টেক্সট_ফ্যাক্টরি সেট করুন:

connection = sqlite3.connect(...)
connection.text_factory = str

7
এটি আপনাকে বিভিন্ন এনকোডিংগুলিতে সমস্যা দিতে পারে, যেহেতু আপনি এখনও বাইনারি ডেটাটিকে পাঠ্য হিসাবে পার্স করার চেষ্টা করছেন। এর পরিবর্তে স্ক্লাইট3.বাইনারি ব্যবহার করা ভাল।
মারিওভিলাস

35

সমাধানটি পেয়েছি, অনুসন্ধানে আমার আরও কিছুটা সময় ব্যয় করা উচিত ছিল।

সমাধানটি পাইথন 'বাফার' হিসাবে এর মতো মানকে 'কাস্ট' করা হয়:

c.execute('insert or ignore into blah values (?, ?)',(cid, buffer(zlib.compress(html))))

আশা করি এটি অন্য কাউকে সহায়তা করবে।


4
যখন আমি এটি করেছি, আমার ডাটাবেস বেস 36 টি পাঠ্যে পূর্ণ ছিল, যা সরাসরি ব্লব সংরক্ষণের চেয়ে ডাটাবেসটিকে আরও বড় করে তুলবে।
ব্রায়ান মিন্টন

4
এটি ভুল, আপনার ডকুমেন্টেশন যেমনটি বলছে তার পরিবর্তে sqlite3 ব্যবহার করা উচিত B
মারিওভিলাস

দেখে মনে হচ্ছে স্ক্যালিটি ৩. বাইনারি () কেবল বাফারের একটি নাম (), কমপক্ষে github.com/ghaering/pysqlite/blob/master/lib/dbapi2.py#L54
স্টিভেট

হু। এবং এটি সাইক্লাইট ডকসের এই বিভাগটি দেখতে আসলে বাফার () ব্যবহারকে উত্সাহ দেয়: "নিম্নলিখিত পাইথন প্রকারগুলি কোনও সমস্যা ছাড়াই এসকিউএলাইটে প্রেরণ করা যেতে পারে: ..." [পাইথন টাইপ] বাফার ... [এসকিউএলাইট টাইপ] বিএলবিও
স্টিভেট

35

বিএলওবি টাইপের সাথে কাজ করার জন্য আপনাকে প্রথমে আপনার জ্লিব সংক্ষেপিত স্ট্রিংটিকে বাইনারি ডেটাতে রূপান্তর করতে হবে - অন্যথায় স্ক্লাইটটি এটিকে একটি পাঠ্য স্ট্রিং হিসাবে প্রক্রিয়া করার চেষ্টা করবে। এটি স্ক্লাইট 3.বাইনারি () দিয়ে করা হয়। উদাহরণ স্বরূপ:

c.execute('insert or ignore into blah values (?, ?)',(cid, 
sqlite3.Binary(zlib.compress(html))))

এইটা কাজ করে. যাইহোক, আমি কেন এটি প্রয়োজন তা ভাবছিলাম। "BLOB" টাইপটি ইতিমধ্যে এই কলামে থাকা ডেটা বাইনারি হওয়ার ইঙ্গিত দেয়? পাইথন 2-এ দ্রষ্টব্য পাঠ্য বা বাইনারি হতে পারে। Sqlite3 কি কেবল BLOB ধরণের জন্য বাইনারি হিসাবে বস্তুর (zlib সংক্ষেপিত স্ট্রিং) আচরণ করবে না?
ব্যবহারকারী 1783732

আমি মনে করি না পাইথনের সম্পূর্ণ ডেটাবেস স্কিমার মেমোরিতে সঠিক ডেটা ধরণের পরামর্শের জন্য রয়েছে - সম্ভবত এটি রানটাইমের উপর নির্ভর করে যেগুলি আপনি এটি পাস করেছেন তার উপর ভিত্তি করে বাইনারি স্ট্রিংটি একটি পাঠ্য স্ট্রিং থেকে আলাদা করা যায় না differe
মারিওভিলাস

কারণ এসকিউএলাইট ডায়নামিক টাইপ ব্যবহার করে: sqlite.org/datatype3.html @ user1783732
লেস্টার চিউং

1

বাক্য গঠন:

সম্ভাব্য স্টোরেজ 5 ধরণের: নুল, ইন্টিগের, পাঠ্য, বাস্তব এবং ব্লগ

বিএলওবি সাধারণত আচারযুক্ত মডেল বা ডিল আচারযুক্ত মডেলগুলি সঞ্চয় করতে ব্যবহৃত হয়

> cur.execute('''INSERT INTO Tablename(Col1, Col2, Col3, Col4) VALUES(?,?,?,?)''', 
                                      [TextValue, Real_Value, Buffer(model), sqlite3.Binary(model2)])
> conn.commit()

> # Read Data:
> df = pd.read_sql('SELECT * FROM Model, con=conn) 
> model1 = str(df['Col3'].values[0]))
> model2 = str(df['Col'].values[0]))

0

আপনি কাঁচা আউটপুটের পরিবর্তে repr (html) ব্যবহার করে মানটি সংরক্ষণ করতে পারেন এবং ব্যবহারের জন্য মানটি পুনরুদ্ধার করার সময় eval (html) ব্যবহার করতে পারেন।

c.execute('insert or ignore into blah values (?, ?)',(1, repr(zlib.compress(html))))

4
এর মতো ইওল এবং রিটার ব্যবহার করা খুব ময়লা। আপনি কোনও ডেটা-উত্সকে কতটা বিশ্বাস করেন তা নয়।
জেসন ফ্রাইড

আমি সম্মতি জানাই, এখানে eval () এর চেয়ে ভাল কিছু। সঠিক সমাধানটি sqlite3.Bাইনারি ব্যবহার করছে, তবে আপনি যদি কোনও কারণে না করতে পারেন তবে নিরাপদ উপায়ে ডেটা এনকোড করা ভাল - উদাহরণস্বরূপ বেস 64।
মারিওভিলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.