2016-10-11 14 views
5

Tôi đang có cột loại NVARCHAR trong cơ sở dữ liệu của mình. Tôi không thể chuyển đổi nội dung của cột này thành chuỗi đơn giản trong mã của tôi. (Tôi đang sử dụng pyodbc để kết nối cơ sở dữ liệu).Sự cố mã hóa/giải mã chuỗi - ký tự bị thiếu từ cuối

# This unicode string is returned by the database 
>>> my_string = u'\u4157\u4347\u6e65\u6574\u2d72\u3430\u3931\u3530\u3731\u3539\u3533\u3631\u3630\u3530\u3330\u322d\u3130\u3036\u3036\u3135\u3432\u3538\u2d37\u3134\u3039\u352d' 

# prints something in chineese 
>>> print my_string 
䅗䍇湥整⵲㐰㤱㔰㜱㔹㔳㘱㘰㔰㌰㈭㄰〶〶ㄵ㐲㔸ⴷㄴ〹㔭 

Gần nhất tôi đã đi là thông qua mã hóa nó để utf-16 như:

>>> my_string.encode('utf-16') 
'\xff\xfeWAGCenter-04190517953516060503-20160605124857-4190-5' 
>>> print my_string.encode('utf-16') 
��WAGCenter-04190517953516060503-20160605124857-4190-5 

Nhưng giá trị thực tế mà tôi cần theo các cửa hàng giá trị trong cơ sở dữ liệu là:

WAGCenter-04190517953516060503-20160605124857-4190-51 

Tôi đã thử mã hóa nó thành utf-8, utf-16, ascii, utf-32 nhưng không có gì có vẻ hiệu quả.

Có ai có ý tưởng về những gì tôi bị thiếu không? Và cách lấy kết quả mong muốn từ my_string.

Sửa: On chuyển đổi nó để utf-16-le, tôi có thể để loại bỏ ký tự không mong muốn từ đầu, nhưng vẫn là một nhân vật là mất tích từ cuối

>>> print t.encode('utf-16-le') 
WAGCenter-04190517953516060503-20160605124857-4190-5 

Mở cố gắng cho một số cột khác, nó đang làm việc. Điều gì có thể là nguyên nhân gây ra sự cố gián đoạn này?

+0

Bạn đang nhìn thấy một dấu thứ tự byte (BOM) – brianpck

+0

@brianpck Dấu ngoặc đơn lúc bắt đầu + thiếu 1 ở cuối. Tôi đang điều tra về * Dấu đơn hàng Byte * ngay bây giờ. Bất kỳ ý tưởng tại sao '1' bị thiếu trong lần cuối? – user7001260

+1

Các ký tự trong 'my_string' * là * các điểm mã cjk sao cho không thể là những gì thực sự được trả về từ trường' nvarchar'? Nếu có thể luôn luôn có thể đọc nó như là một 'varchar' với một diễn viên' chọn cast (trường như varchar (xxx)) ... ' –

Trả lời

2

Bạn có vấn đề lớn trong định nghĩa cơ sở dữ liệu, theo cách bạn lưu trữ các giá trị trong đó hoặc theo cách bạn đọc các giá trị từ nó. Tôi chỉ có thể giải thích những gì bạn đang nhìn thấy, nhưng không phải tại sao cũng không làm thế nào để sửa chữa nó mà không:

  • loại cơ sở dữ liệu
  • cách bạn giá trị đầu vào trong đó
  • theo cách bạn trích xuất các giá trị để có được giả của bạn unicode chuỗi
  • nội dung thực tế nếu bạn sử dụng trực tiếp (mẹ đẻ) truy cập cơ sở dữ liệu

Wh bạn nhận được là một chuỗi ASCII, trong đó các ký tự 8 bit được nhóm theo cặp để xây dựng các ký tự unicode 16 bit theo thứ tự nhỏ. Vì chuỗi dự kiến ​​có một số ký tự lẻ, ký tự cuối cùng bị mất (dịch), vì chuỗi gốc kết thúc bằng u'\352d' trong đó 0x2d là mã ASCII cho '-' và 0x35 cho '5'. Demo:

def cvt(ustring): 
    l = [] 
    for uc in ustring: 
     l.append(chr(ord(uc) & 0xFF)) # low order byte 
     l.append(chr((ord(uc) >> 8) & 0xFF)) # high order byte 
    return ''.join(l) 

cvt(my_string) 
'WAGCenter-04190517953516060503-20160605124857-4190-5' 
+0

Tôi thừa nhận điều này không trả lời câu hỏi, nhưng đó là điều tốt nhất tôi có thể làm với các thông tin đã cho, và nó quá phức tạp cho nhận xét –

+0

Tôi đang sử dụng 'Netezza' như một công cụ cơ sở dữ liệu. và tôi không thể mã hóa nó thành 'ascii'. Tôi đã cấu hình 'pyodbc' cho' utf-16'. Hãy cho tôi biết bạn cần thêm chi tiết nào? Cảm ơn lời giải thích. Tôi biết có điều gì đó sai, nhưng tôi không biết phải kiểm tra ở đâu. Ngoài ra, cơ sở dữ liệu này tôi đang sử dụng thuộc về nhóm khác nhau, tôi chỉ có thể thay đổi cấu hình ở cấp dự án của tôi. – user7001260

+0

@ user7001260: bạn có thể định cấu hình pyodbc cho mã hóa latin1 không? Latin1 chỉ chứa 256 mã đầu tiên của unicode. –

1

Vấn đề này đã được, tôi đã sử dụng trong tập tin UTF-16odbcinst.ini tôi nơi như tôi đã phải sử dụng UTF-8 định dạng mã hóa ký tự.

Trước đó tôi đã thay đổi thông số này thành thông số OPTION trong khi thực hiện kết nối với PyODBC. Nhưng sau đó thay đổi nó trong odbcinst.ini tệp đã khắc phục sự cố.

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