2012-11-07 16 views
6

मैं mysql में डेटाबेस बनाता हूं और अपना वेब सर्वर बनाने के लिए वेबपी का उपयोग करता हूं।क्यों वेबपी का उपयोग करते समय चीनी खराब हो गए लेकिन MySQLdb का उपयोग करते समय यह सामान्य है?

लेकिन यह क्रमशः डेटाबेस तक पहुंचने के लिए वेबपी और MySQLdb के व्यवहार के बीच चीनी चरित्र के लिए बहुत अजीब है।

मेरे तालिका t_test (UTF8 databse):

id  name 
1  测试 

"测试" के लिए UTF8 कोड है: XAF \ X95

\ xe8 \ \ x8b \ xb5 \ XE6

नीचे मेरी समस्या है

जब MySQLdb करने के लिए का उपयोग कर "का चयन करें" इस तरह:

c=conn.cursor() 
    c.execute("SELECT * FROM t_test") 
    items = c.fetchall() 
    c.close() 
    print "items=%s, name=%s"%(eval_items, eval_items[1]) 

परिणाम सामान्य है, यह प्रिंट:

items=(127L, '\xe6\xb5\x8b\xe8\xaf\x95'), name=测试 

लेकिन जब मैं का उपयोग webpy एक ही बातें करते हैं:

db = web.database(dbn='mysql', host="127.0.0.1", 
      user='test', pw='test', db='db_test', charset="utf8") 
    eval_items=db.select('t_test') 
    comment=eval_items[0].name 
    print "comment code=%s"%repr(comment) 
    print "comment=%s"%comment.encode("utf8") 

चीनी तोड़ना-मरोड़ना हुई, प्रिंट परिणाम है:

comment code=u'\xe6\xb5\u2039\xe8\xaf\u2022' 
    comment=忙碌鈥姑€ 

मैं जानता हूँ कि webpy के डाटाबेस भी MySQLdb पर निर्भर है, लेकिन यह इन दो तरीकों से बहुत अलग है। क्यूं कर?

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

+2

दरअसल - जिस स्ट्रिंग को आप पुनर्प्राप्त करते हैं वह टोब ई कचरा दिखाई देता है। शायद डेटाबेस में teh डेटा utf-8 में एन्कोड नहीं किया गया है? यह कैसे दर्ज किया गया? – jsbueno

+0

मुझे यकीन है कि मेरे डेटाबेस में डेटा भी utf-8 है। मैं अपनी mysql तालिका की जांच करने के लिए Navicat का उपयोग करता हूं, और "测试" के लिए हेक्स कोड है: E6B5 8BE8 AF95। और, आप इसे देखने के लिए UtraEdit का उपयोग कर सकते हैं। @jsbueno – eason

+0

यह सुनिश्चित नहीं है कि प्रासंगिक है, लेकिन जब मैं गड़बड़ी वाली स्ट्रिंग मुद्रित करता हूं तो मुझे यह मिलता है: http://codepad.org/o3DgYhxr, æμ <è¯ • 忙碌 鈥 姑  € के बजाय। आप अपनी स्ट्रिंग को कहां प्रिंट कर रहे हैं? –

उत्तर

1

वास्तव में, कुछ गलत हो रहा है - जैसा कि आपने अपनी टिप्पणी पर कहा है, यूनिकोड repr।

>>> d 
'\xe6\xb5\x8b\xe8\xaf\x95' 
>>> print d 
测试 

लेकिन अपने "टिप्पणी" यूनिकोड वस्तु पर बाइट्स को देखो:

comment code=u'\xe6\xb5\u2039\xe8\xaf\u2022' 

अर्थ हिस्सा जो यहाँ मेरी utf-8 टर्मिनल पर काम करता है - "测试" के लिए बाइट्स हैं E6B5 8BE8 AF95 अपनी सामग्री के टिप्पणी के लिए UTF-8 बाइट (वर्ण "\ XYY" और भाग यूनिकोड के रूप में एन्कोड किया गया है के रूप में प्रतिनिधित्व (घर का काम) \ uYYYY साथ प्रतिनिधित्व किया अंक हैं - यह इंगित करता है गंभीर कचरा

MySQL है। कुछ बिल्ली उचित डीकोड (utf-8 या अन्यथा) को में एन्कोड किया गया है - जिसमें से एक कनेक्शन में उचित "वर्णसेट" पैरामीटर पास कर रहा है। लेकिन आपने पहले से ही ऐसा किया -

एक प्रयास आप कर सकते हैं कि कनेक्शन use_unicode=False - विकल्प को पास करने और अपने कोड में utf-8 तारों को डीकोड करना है।

db = web.database(dbn='mysql', host="127.0.0.1", 
     user='test', pw='test', db='db_test', charset="utf8", use_unicode=False) 

चेक विकल्प इस और अन्य पैरामीटर के लिए कनेक्ट करने के लिए कोशिश कर सकते हैं:

http://mysql-python.sourceforge.net/MySQLdb.html

बावजूद होने का यह सही ढंग से काम करने के लिए, संकेत के साथ ऊपर, मैं के लिए एक समाधान मिल गया आप - यह यूनिकोड वर्णों की तरह दिखता है (यूनिकोड ऑब्जेक्ट्स में यूटीएफ -8 कच्चे बाइट्स नहीं) आपकी एन्कोडेड स्ट्रिंग में इन एन्कोडिंग में से एक में एन्कोड किया गया है: ("cp1258", "cp1252", "पाल्मोस", " सीपी 1254 ")

इनमें से, cp1252 लगभग "लैटिन 1" जैसा ही है - जो डिफ़ॉल्ट वर्णसेट MySQL का उपयोग करता है यदि उसे कनेक्शन में "वर्णसेट" तर्क नहीं मिलता है। लेकिन यह केवल वेब 2py के डेटाबेस को पास नहीं कर रहा है, क्योंकि आपको मैंगल्ड वर्ण मिल रहे हैं, सिर्फ गलत एन्कोडिंग नहीं - ऐसा लगता है जैसे web2py एन्कोडिंग और आपकी स्ट्रिंग को आगे और आगे डीकोड कर रहा है, और एन्कोडिंग त्रुटियों को अनदेखा कर रहा है

इन एन्कोडिंग के सभी से मैं एक utf-8 बाइट स्ट्रिंग के रूप में अपने मूल "测试" स्ट्रिंग को पुनः प्राप्त कर सके, कर रही है, उदाहरण के लिए:

comment = comment.encode("cp1252", errors="ignore") 

तो, यह लाइन रखने के लिए अब काम कर सकते हैं, लेकिन यूनिकोड के साथ अनुमान लगाना कभी अच्छा नहीं होता - प्रोपर चीज वेब 2py को कम करने के लिए है जो आपको पहले अर्द्ध-डीकोडेड यूटीएफ -8 तारों को देने के लिए है जगह, और इसे वहाँ रोको।

अद्यतन

मैं यहाँ जाँच की यह क्या हो रहा है - सही utf-8 '\xe6\xb5\x8b\xe8\xaf\x95' स्ट्रिंग mysql से पढ़ी जाती है, और आप के लिए यह पहुंचाने (use_unicode = सच मामले में) से पहले 0 - इन बाइट्स को डीकोड किया जा रहा है जैसे कि वे "cp1252" werhe - यह गलत u'\xe6\xb5\u2039\xe8\xaf\u2022' यूनिकोड उत्पन्न करता है। यह शायद एक वेब 2py त्रुटि है, जैसे, यह आपके "charset = utf8" पैरामीटर को वास्तविक कनेक्शन में पास नहीं करता है। जब आप कच्चे बाइट्स देने के बजाय "use_unicode = False" सेट करते हैं, तो यह स्पष्ट रूप से गलत यूटोड को चुनता है, जो इसे "utf-8" का उपयोग करके एक डीकोड करता है - यह '\xc3\xa6\xc2\xb5\xe2\x80\xb9\xc3\xa8\xc2\xaf\xe2\x80\xa2' अनुक्रम उत्पन्न करता है जिस पर आपने टिप्पणी की है (जो और भी गलत है) ।

सब सब में, वैकल्पिक हल मैं उपर्युक्त मूल, सही स्ट्रिंग को पुनः प्राप्त करने क्योकि गलत यूनिकोड को देखते हुए u'\xe6\xb5\u2039\xe8\xaf\u2022'.encode("cp1252", errors="ignore") कर एक ही रास्ता लगता है - कुछ अन्य बात कर रहे करने के लिए जो है, से कम सेट अप डेटाबेस कनेक्शन (या शायद, web2py या mysql ड्राइवरों को अद्यतन संभव हो तो)

** अद्यतन 2 ** मैं futrher कोड web2py dal.py फ़ाइल अपने आप में जाँच की है - यह सेटअप करने के लिए डिफ़ॉल्ट रूप से UTF-8 के रूप में कनेक्शन का प्रयास - लेकिन ऐसा लगता है कि यह MySQLdb और pymysql ड्राइवर दोनों को आज़माएगा - यदि आपने दोनों स्थापित किए हैं, तो pymysql को अनइंस्टॉल करने का प्रयास करें, और केवल MySQLdb छोड़ दें।

+0

अपने विस्तृत विश्लेषण का धन्यवाद! चूंकि यह आपके द्वारा दिए गए 2 चरणों के बाद काम नहीं कर सकता है, यह अभी भी निर्देशक है। जब मैंने "use_unicode = गलत" के साथ कनेक्शन सेट किया, तो मुझे repr (टिप्पणी) मिली: \ xc3 \ xa6 \ xc2 \ xb5 \ xe2 \ x80 \ xb9 \ xc3 \ xa8 \ xc2 \ xaf \ xe2 \ x80 \ xa2, यह है Utf8 एन्कोड नहीं। फिर मैं इसे cp1252 (अनदेखा) के साथ एन्कोड करता हूं, लेकिन यह अभी तक विफल रहा है। बीटीडब्लू: मेरे मूल प्रश्न में, वेब स्ट्रिप का उपयोग करते समय "स्ट्रेंज" का अर्थ वास्तव में अर्द्ध यूटीएफ 8 और सेमी यूनिकोड था, जैसा कि आपने पहले कभी कहा था। तो, मुझे लगता है कि यह शायद वेबपी की बग है। – eason

+0

यदि कोई उपरोक्त अनुक्रम को डीकोड करने का प्रयास करता है जैसे कि यूटीएफ -8 में, कोई आपको जो प्राप्त करता है उसे प्राप्त करता है: 'u' \ xe6 \ xb5 \ u2039 \ xe8 \ xaf \ u2022'now- कम से कम हम जानते हैं web2py वहाँ कैसे मिला – jsbueno