Pesan kesalahan
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2026'
in position 35: ordinal not in range(256)
tampaknya menunjukkan bahwa beberapa kode bahasa Python mencoba mengonversi karakter \u2026
menjadi string Latin-1 (ISO8859-1), dan gagal. Tidak mengherankan, karakter itu adalah U+2026 HORIZONTAL ELLIPSIS
, yang tidak memiliki satu karakter setara dalam ISO8859-1.
Anda memperbaiki masalah dengan menambahkan kueri ?charset=utf8
dalam panggilan koneksi SQLAlchemy Anda:
import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table
db = create_engine('mysql://user:[email protected]/db?charset=utf8')
Bagian URL Basis Data
dari dokumentasi SQLAlchemy memberi tahu kita bahwa URL yang dimulai dengan mysql
menunjukkan dialek MySQL, menggunakan mysql-python
pengemudi.
Bagian berikut, DBAPI Khusus connect() argumen , memberi tahu kita bahwa argumen kueri diteruskan ke DBAPI yang mendasarinya.
Jadi, apa fungsi mysql-python
driver membuat parameter {charset: 'utf8'}
? Bagian Fungsi dan atribut
dokumentasi mereka mengatakan tentang charset
atribut "...Jika ada, set karakter koneksi akan diubah ke set karakter ini, jika tidak sama."
Untuk mengetahui apa arti rangkaian karakter koneksi, kita buka 10.1.4. Kumpulan dan Koleksi Karakter Koneksi dari manual referensi MySQL 5.6. Singkatnya, MySQL dapat menginterpretasikan kueri yang masuk sebagai pengkodean yang berbeda dari kumpulan karakter database, dan berbeda dari pengkodean hasil kueri yang dikembalikan.
Karena pesan kesalahan yang Anda laporkan terlihat seperti Python daripada pesan kesalahan SQL, saya akan berspekulasi bahwa sesuatu di SQLAlchemy atau mysql-python mencoba mengonversi kueri ke penyandian koneksi default latin-1
sebelum mengirimnya. Inilah yang memicu kesalahan. Namun, string kueri ?charset=utf8
di connect()
. Anda panggilan mengubah penyandian koneksi, dan U+2026 HORIZONTAL ELLIPSIS
mampu melewatinya.
Pembaruan: Anda juga bertanya, "jika saya menghapus opsi charset dan kemudian menyandikan deskripsi menggunakan .encode('cp1252') itu akan berjalan dengan baik. Bagaimana elipsis dapat melewati dengan cp1252 tetapi tidak unicode?"
mengkodekan cp1252
memiliki
karakter elipsis horizontal pada nilai byte \x85
. Dengan demikian dimungkinkan untuk mengkodekan string Unicode yang berisi U+2026 HORIZONTAL ELLIPSIS
ke cp1252 tanpa kesalahan.
Ingat juga bahwa dalam Python, string Unicode dan string byte adalah dua tipe data yang berbeda. Masuk akal untuk berspekulasi bahwa MySQLdb mungkin memiliki kebijakan hanya mengirim string byte melalui koneksi SQL. Jadi itu akan mengkodekan kueri yang diterima sebagai string Unicode menjadi string byte, tetapi akan membiarkan kueri diterima sebagai string byte saja. (Ini spekulasi, saya belum melihat kode sumbernya.)
Dalam traceback yang Anda posting, dua baris terakhir (paling dekat dengan tempat kesalahan terjadi) menunjukkan nama metode literal
, diikuti oleh unicode_literal
. Itu cenderung mendukung teori bahwa MySQLdb mengkodekan kueri yang diterimanya sebagai string Unicode menjadi string byte.
Saat Anda menyandikan string kueri sendiri, Anda melewati bagian MySQLdb yang melakukan pengkodean ini secara berbeda. Namun, perhatikan bahwa jika Anda menyandikan string kueri secara berbeda dari panggilan rangkaian karakter koneksi MySQL, maka Anda akan mengalami ketidakcocokan penyandian, dan teks Anda kemungkinan besar akan disimpan dengan salah.