Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm cách nào để SQLAlchemy chèn chính xác dấu chấm lửng unicode vào bảng mySQL?

Thông báo lỗi

UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2026' 
in position 35: ordinal not in range(256)

dường như chỉ ra rằng một số mã ngôn ngữ Python đang cố gắng chuyển đổi ký tự \u2026 thành một chuỗi Latin-1 (ISO8859-1) và nó không thành công. Không có gì đáng ngạc nhiên, ký tự đó là U+2026 HORIZONTAL ELLIPSIS , không có ký tự tương đương duy nhất trong ISO8859-1.

Bạn đã khắc phục sự cố bằng cách thêm truy vấn ?charset=utf8 trong lệnh gọi kết nối SQLAlchemy của bạn:

import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table

db = create_engine('mysql://user:[email protected]/db?charset=utf8')

Phần Url cơ sở dữ liệu của tài liệu SQLAlchemy cho chúng ta biết rằng một URL bắt đầu bằng mysql cho biết phương ngữ MySQL, sử dụng mysql-python người lái xe.

Phần sau, DBAPI tùy chỉnh đối số connect () , cho chúng tôi biết rằng các đối số truy vấn được chuyển đến DBAPI bên dưới.

Vậy, mysql-python có chức năng gì trình điều khiển tạo tham số {charset: 'utf8'} ? Phần Hàm và thuộc tính trong tài liệu của họ nói về charset thuộc tính "... Nếu có, bộ ký tự kết nối sẽ được thay đổi thành bộ ký tự này, nếu chúng không bằng nhau."

Để tìm hiểu ý nghĩa của bộ ký tự kết nối, chúng tôi chuyển sang 10.1.4. Bộ ký tự kết nối và ảnh ghép của sổ tay tham khảo MySQL 5.6. Để ngắn gọn một câu chuyện dài, MySQL có thể diễn giải các truy vấn đến dưới dạng mã hóa khác với bộ ký tự của cơ sở dữ liệu và khác với mã hóa của kết quả truy vấn được trả về.

Vì thông báo lỗi bạn đã báo cáo trông giống như một Python chứ không phải là một thông báo lỗi SQL, tôi sẽ suy đoán rằng một cái gì đó trong SQLAlchemy hoặc mysql-python đang cố chuyển đổi truy vấn thành một mã hóa kết nối mặc định của latin-1 trước khi gửi nó. Đây là những gì gây ra lỗi. Tuy nhiên, chuỗi truy vấn ?charset=utf8 trong connect() của bạn cuộc gọi thay đổi mã hóa kết nối và U+2026 HORIZONTAL ELLIPSIS có thể vượt qua.

Cập nhật: bạn cũng hỏi, "nếu tôi xóa tùy chọn bộ ký tự và sau đó mã hóa mô tả bằng .encode ('cp1252'), nó sẽ hoạt động tốt. Làm thế nào để một dấu chấm lửng có thể truy cập với cp1252 nhưng không phải unicode?"

mã hóa cp1252 một ký tự dấu chấm lửng ngang ở giá trị byte \x85 . Do đó, có thể mã hóa một chuỗi Unicode chứa U+2026 HORIZONTAL ELLIPSIS thành cp1252 mà không bị lỗi.

Cũng nên nhớ rằng trong Python, chuỗi Unicode và chuỗi byte là hai kiểu dữ liệu khác nhau. Thật hợp lý khi suy đoán rằng MySQLdb có thể có chính sách chỉ gửi các chuỗi byte qua kết nối SQL. Do đó, nó sẽ mã hóa một truy vấn nhận được dưới dạng chuỗi Unicode thành một chuỗi byte, nhưng sẽ để lại một truy vấn nhận được dưới dạng chuỗi byte. (Đây là suy đoán, tôi chưa xem mã nguồn.)

Trong phần theo dõi mà bạn đã đăng, hai dòng cuối cùng (gần nhất với vị trí xảy ra lỗi) hiển thị tên phương thức literal , theo sau là unicode_literal . Điều đó có xu hướng ủng hộ lý thuyết rằng MySQLdb đang mã hóa truy vấn mà nó nhận được dưới dạng chuỗi Unicode thành chuỗi byte.

Khi bạn tự mã hóa chuỗi truy vấn, bạn bỏ qua phần MySQLdb thực hiện mã hóa này theo cách khác. Tuy nhiên, lưu ý rằng nếu bạn mã hóa chuỗi truy vấn khác với lệnh gọi của bộ ký tự kết nối MySQL, thì bạn sẽ có mã hóa không khớp và văn bản của bạn có thể sẽ bị lưu trữ sai.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chọn các hàng MYSQL có cùng tên trường và thêm tiền tố

  2. Ẩn ID đối tượng cơ sở dữ liệu thực trong url

  3. MySQL sao chép hiệu quả tất cả các bản ghi từ bảng này sang bảng khác

  4. Cách lấy năm và tháng từ ngày trong MySQL

  5. Làm cách nào để xuất cơ sở dữ liệu từ phiên bản Amazon RDS MySQL sang phiên bản cục bộ?