Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bagaimana cara mendapatkan SQLAlchemy untuk memasukkan elipsis unicode dengan benar ke dalam tabel mySQL?

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menghubungkan mysql dengan swift?

  2. Cara melihat kesalahan kueri di PDO PHP

  3. Cara Menemukan dan Mengganti Teks di Database MySQL menggunakan SQL

  4. Membunuh kueri MySQL selama eksekusi dengan PHP dan AJAX

  5. Cara Membuat Tampilan MySQL