2013-02-26 43 views
33

Tôi đang thực hiện một số tập lệnh trong python. Tôi tạo một chuỗi mà tôi lưu trong một tập tin. Chuỗi này có rất nhiều dữ liệu, đến từ arborescence và tên tập tin của một thư mục. Theo convmv, tất cả các arborescence của tôi là trong UTF-8.mã hóa python utf-8

Tôi muốn giữ mọi thứ trong UTF-8 vì tôi sẽ lưu nó trong MySQL sau. Hiện tại, trong MySQL, trong UTF-8, tôi gặp một số vấn đề với một số ký tự (như é hoặc è - I'am tiếng Pháp).

Tôi muốn con trăn đó luôn sử dụng chuỗi như UTF-8. Tôi đọc một số thông tin trên internet và tôi đã làm như thế này.

Kịch bản của tôi bắt đầu với điều này:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 
def createIndex(): 
    import codecs 
    toUtf8=codecs.getencoder('UTF8') 
    #lot of operations & building indexSTR the string who matter 
    findex=open('config/index/music_vibration_'+date+'.index','a') 
    findex.write(codecs.BOM_UTF8) 
    findex.write(toUtf8(indexSTR)) #this bugs! 

Và khi tôi thực hiện, đây là câu trả lời: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2171: ordinal not in range(128)

Edit: Tôi thấy, trong tập tin của tôi, giọng đều độc đáo bằng văn bản. Sau khi tạo tập tin này, tôi đọc nó và tôi viết nó vào MySQL. Nhưng tôi không hiểu tại sao, nhưng tôi gặp vấn đề với mã hóa. Cơ sở dữ liệu MySQL của tôi nằm trong utf8 hoặc có vẻ là truy vấn SQL SHOW variables LIKE 'char%' trả về tôi chỉ utf8 hoặc nhị phân.

chức năng của tôi trông như thế này:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

def saveIndex(index,date): 
    import MySQLdb as mdb 
    import codecs 

    sql = mdb.connect('localhost','admin','*******','music_vibration') 
    sql.charset="utf8" 
    findex=open('config/index/'+index,'r') 
    lines=findex.readlines() 
    for line in lines: 
     if line.find('#artiste') != -1: 
      artiste=line.split('[:::]') 
      artiste=artiste[1].replace('\n','') 

      c=sql.cursor() 
      c.execute('SELECT COUNT(id) AS nbr FROM artistes WHERE nom="'+artiste+'"') 
      nbr=c.fetchone() 
      if nbr[0]==0: 
       c=sql.cursor() 
       iArt+=1 
       c.execute('INSERT INTO artistes(nom,status,path) VALUES("'+artiste+'",99,"'+artiste+'/")'.encode('utf8') 

Và nghệ sĩ đang độc đáo hiển thị trong file viết xấu vào BDD. Vấn đề là gì?

+0

Mã mẫu python của bạn không hợp lệ; có lỗi cú pháp ở ít nhất 2 địa điểm. Bạn có thể sửa những cái đầu tiên được không? –

+0

Bạn có lưu tệp dưới dạng utf-8 chứ không phải tệp ascii không? – QuentinUK

Trả lời

45

Bạn không cần mã hóa dữ liệu được mã hóa đã được. Khi bạn cố gắng làm điều đó, trước tiên Python sẽ cố gắng để giải mã nó thành unicode trước khi mã hóa nó trở lại UTF-8. Đó là những gì đang thất bại ở đây:

>>> data = u'\u00c3'   # Unicode data 
>>> data = data.encode('utf8') # encoded to UTF-8 
>>> data 
'\xc3\x83' 
>>> data.encode('utf8')   # Try to *re*-encode it 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128) 

Chỉ cần ghi dữ liệu của bạn trực tiếp đến tập tin, có không cần để mã hóa dữ liệu đã được mã hóa.

Nếu bạn thay vì xây dựng các giá trị unicode thay vào đó, bạn thực sự sẽ phải mã hóa những giá trị đó để có thể ghi vào tệp. Thay vào đó, bạn muốn sử dụng codecs.open(), trả về một đối tượng tệp sẽ mã hóa các giá trị unicode thành UTF-8 cho bạn.

Bạn cũng thực sự không muốn viết ra những BOM UTF-8, trừ bạn để hỗ trợ các công cụ của Microsoft mà không thể đọc UTF-8 khác (chẳng hạn như MS Notepad).

Đối với vấn đề chèn MySQL của bạn, bạn cần phải làm hai việc:

  • Thêm charset='utf8'-MySQLdb.connect() cuộc gọi của bạn.

  • Sử dụng unicode đối tượng, không str đối tượng khi truy vấn hoặc chèn, nhưng sử dụng các thông số sql để kết nối MySQL có thể làm những điều đúng đắn dành cho bạn:

    artiste = artiste.decode('utf8') # it is already UTF8, decode to unicode 
    
    c.execute('SELECT COUNT(id) AS nbr FROM artistes WHERE nom=%s', (artiste,)) 
    
    # ... 
    
    c.execute('INSERT INTO artistes(nom,status,path) VALUES(%s, 99, %s)', (artiste, artiste + u'/')) 
    

Nó thực sự có thể làm việc tốt hơn nếu bạn đã sử dụng codecs.open() để giải mã nội dung tự động thay thế:

import codecs 

sql = mdb.connect('localhost','admin','ugo&([email protected]','music_vibration', charset='utf8') 

with codecs.open('config/index/'+index, 'r', 'utf8') as findex: 
    for line in findex: 
     if u'#artiste' not in line: 
      continue 

     artiste=line.split(u'[:::]')[1].strip() 

    cursor = sql.cursor() 
    cursor.execute('SELECT COUNT(id) AS nbr FROM artistes WHERE nom=%s', (artiste,)) 
    if not cursor.fetchone()[0]: 
     cursor = sql.cursor() 
     cursor.execute('INSERT INTO artistes(nom,status,path) VALUES(%s, 99, %s)', (artiste, artiste + u'/')) 
     artists_inserted += 1 

Bạn có thể muốn quét lên Unicode và UTF-8 và mã hóa. Tôi có thể giới thiệu các bài viết sau:

+0

Bạn có thấy bảng chỉnh sửa của tôi không? Tôi bị mất ... – vekah

+4

@vekah: Bạn đã làm theo hướng dẫn trong [Viết UTF-8 String tới MySQL bằng Python] (http://stackoverflow.com/q/6202726) –

Các vấn đề liên quan