Hóa ra, đó là vấn đề khá khó xử. Tóm lại, hầu hết các biến thể và loài trong Kiểu dữ liệu chuỗi MySQL ánh xạ tới một kiểu dữ liệu duy nhất trong giao diện của MySQL với cờ BINARY bổ sung.
Do đó, VARCHAR
của MySQL , VARBINARY
và một chuỗi ký tự ánh xạ tới cùng một MySQLdb.constants.FIELD_TYPE.VAR_STRING
nhập định nghĩa loại cột, nhưng có thêm MySQLdb.constants.FLAG.BINARY
gắn cờ khi loại là VARBINARY
hoặc một chuỗi được đối chiếu với *_bin
đối chiếu.
Mặc dù có MySQLdb.constants.FIELD_TYPE.VARCHAR
loại, tôi không tìm ra nó được sử dụng khi nào. Như tôi đã nói, MySQL VARCHAR
các cột ánh xạ tới FIELD_TYPE.VAR_STRING
.
Giải pháp trở nên khá mong manh, nếu ứng dụng của bạn sử dụng các chuỗi nhị phân thực sự (ví dụ:bạn lưu trữ hình ảnh và tìm nạp chúng bằng kết nối giống như văn bản), vì nó giả định giải mã tất cả các chuỗi nhị phân thành unicode. Tuy nhiên, nó hoạt động.
Là tài liệu chính thức trạng thái:
Trong thực tế, nỗi đau thực sự trong mông có thể là quá trình xây dựng từ điển trình chuyển đổi của riêng bạn. Nhưng bạn có thể nhập cái mặc định từ MySQLdb.converters.conversions
và vá nó, hoặc thậm chí vá nó trên một phiên bản của Kết nối. Mẹo là xóa một trình chuyển đổi đặc biệt cho một FLAG.BINARY
gắn cờ và thêm bộ giải mã cho mọi trường hợp. Nếu bạn chỉ định rõ ràng một charset
tham số cho MySQLdb.connect
, nó buộc use_unicode=1
tham số này sẽ thêm bộ giải mã cho bạn, nhưng bạn có thể tự làm điều đó:
>>> con = MySQLdb.connect(**params)
>>> con.converter[FIELD_TYPE.VAR_STRING]
[(128, <type 'str'>), (None, <function string_decoder at 0x01FFA130>)]
>>> con.converter[FIELD_TYPE.VAR_STRING] = [(None, con.string_decoder)]
>>> c = con.cursor()
>>> c.execute("SELECT %s COLLATE utf8_bin", u'м')
1L
>>> c.fetchone()
(u'\u043c',)
Bạn có thể cần thực hiện cùng một bản hack cho FIELD_TYPE.STRING
nếu được yêu cầu.
Một giải pháp khác là chuyển use_unicode=0
rõ ràng tới MySQLdb.connect
và thực hiện tất cả các giải mã trong mã của bạn, nhưng tôi thì không.
Hy vọng, điều này có thể hữu ích cho ai đó.