2013-10-04 15 views
6

Tôi có một ứng dụng web sử dụng Flask, SQLAlchemy và WTForms, cùng với các phần mở rộng Flask cần thiết để làm cho nó hoạt động. MySQL đang sử dụng utf8_bin cho tất cả các bảng và cột.Flask, SQLAlchemy và Jinja2 - UnicodeDecodeError

tôi chèn một số chữ Hán và phpMyAdmin hiển thị chúng một cách chính xác nhưng bất cứ khi nào tôi cố gắng để mở một trang tôi nhận được ngoại lệ sau đây:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)

Tôi hiểu rằng tôi nên decode('utf8') các lĩnh vực Tôi muốn hiển thị nhưng shouldn 'Điều này được xử lý bởi SQLAlchemy cho tôi?

Cách duy nhất tôi quản lý để làm cho công việc này là bằng cách duyệt qua danh sách các kết quả và làm điều gì đó tương tự như:

object.property = object.property.decode('utf8')

Nhưng rõ ràng điều này không cần phải được thực hiện bằng tay. Tôi đang thiếu gì?

Cập nhật: lập bản đồ SQLAlchemy

class Thread(db.Model): 

    __tablename__ = 'Thread' 

    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.Unicode(255), nullable=False) 
    body = db.Column(db.Text, nullable=True) 
    date_created = db.Column(db.DateTime, nullable=False, default=datetime.now()) 
    created_by = db.Column(db.Integer, ForeignKey(User.id)) 
    user = relationship(User, backref='threads') 
    display_hash = db.Column(db.Unicode(255), nullable=False, unique=True) 
    display_name = db.Column(db.Unicode(255), nullable=True) 
    nsfw = db.Column(db.Boolean, nullable=False, default=False) 
    last_updated = db.Column(db.DateTime, nullable=False) 

    def __init__(self, title=None, body=None, category_id=None, display_name=None): 
     self.title = title 
     self.body = body 
     self.category_id = category_id 
     self.display_name = display_name 
     self.display_hash = custom_uuid() 
     self.last_updated = self.date_created 

    def __repr__(self): 
     return u'<Thread %r>' % (self.title) 

    def url_title(self): 
     """ Generates an ASCII-only slug. """ 

     result = [] 
     for word in _punct_re.split(self.title.lower()): 
      result.extend(unidecode(word).split()) 
     return unicode(u'-'.join(result)) 

Cập nhật: stack trace

`127.0.0.1 - - [06/Oct/2013 02:37:15] "GET /index HTTP/1.1" 500 - 
Traceback (most recent call last): 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__ 
    return self.wsgi_app(environ, start_response) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app 
    response = self.make_response(self.handle_exception(e)) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception 
    reraise(exc_type, exc_value, tb) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app 
    response = self.full_dispatch_request() 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request 
    rv = self.handle_user_exception(e) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception 
    reraise(exc_type, exc_value, tb) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request 
    rv = self.dispatch_request() 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request 
    return self.view_functions[rule.endpoint](**req.view_args) 
    File "/Users/homedirectory/Projects/Assorted/Fruit Show/app/views.py", line 90, in index 
    return render_template('index.html', threads=threads, pagination=pagination) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/templating.py", line 128, in render_template 
    context, ctx.app) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/flask/templating.py", line 110, in _render 
    rv = template.render(context) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/jinja2/environment.py", line 969, in render 
    return self.environment.handle_exception(exc_info, True) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/jinja2/environment.py", line 742, in handle_exception 
    reraise(exc_type, exc_value, tb) 
    File "/Users/homedirectory/Projects/Assorted/Fruit Show/app/templates/index.html", line 1, in top-level template code 
    {% extends 'base.html' %} 
    File "/Users/homedirectory/Projects/Assorted/Fruit Show/app/templates/base.html", line 50, in top-level template code 
    {% block content %} 
    File "/Users/homedirectory/Projects/Assorted/Fruit Show/app/templates/index.html", line 14, in block "content" 
    <a href="{{ url_for('new_thread') }}/{{ thread.display_hash|safe }}/{{ thread.url_title()|safe }}">{{ thread.title|safe }}</a> 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/jinja2/filters.py", line 747, in do_mark_safe 
    return Markup(value) 
    File "/Users/homedirectory/.virtualenvs/fruitshow/lib/python2.7/site-packages/markupsafe/__init__.py", line 72, in __new__ 
    return text_type.__new__(cls, base) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)` 

Cập nhật: URL cho repo dự án:

https://github.com/ruipacheco/fruitshow

+0

Vui lòng cập nhật câu hỏi của bạn với các mô hình SQLAlchemy mà bạn đang gặp sự cố. –

+0

Cảm ơn bạn đã cập nhật. Bạn cũng có thể cập nhật câu hỏi của mình và cung cấp một đoạn mã ngắn mà bạn có thể sử dụng để sao chép lỗi, bao gồm cả dấu vết ngăn xếp đầy đủ mà mã cung cấp. –

+0

Ngoài ra, MySQL [có thể mặc định kết nối máy khách để sử dụng latin1 ngay cả khi các bảng và cột đang sử dụng unicode] (http://docs.sqlalchemy.org/en/rel_0_8/dialects/mysql.html#unicode). –

Trả lời

4

Sự cố xảy ra với trình điều khiển MySQL mà tôi đang sử dụng.

Tôi đã theo dõi this trả lời và chuyển đổi loại cột từ utf8_bin thành utf8_general_ci đã thực hiện thủ thuật.

0

đặt bộ ký tự trong các tham số kết nối chỉ cho mysql chuyển mã cột từ tuy nhiên chúng nằm trong cơ sở dữ liệu cho mã hóa định dạng được yêu cầu. Dữ liệu vẫn được chuyển giữa MySQL và máy khách dưới dạng byte. Tóm lại, bạn phải thông báo cho sqlalchemy rằng dữ liệu "đặc biệt" này là dữ liệu unicode (trong mã hóa của kết nối). Đối với hầu hết các cột của bạn, bạn đã sử dụng Unicode, phục vụ mục đích này. Điểm nổi bật đáng chú ý là body, là loại Text. Bạn có thể muốn UnicodeText hoặc Text(convert_unicode=True)

+0

Không hoạt động. – ruipacheco

2

Một gợi ý nhỏ cho Slug trường trong Mô hình của bạn.

Có Thư viện được gọi là Webhelpers (https://pypi.python.org/pypi/WebHelpers), nhập tên đó và tiêu đề của bạn sẽ tự động được chuyển đổi thành slug.

Install WebHelpers và sau đó nhập urlify

from webhelpers.text import urlify 
. 
. 
. 
@property 
def slug(self): 
    return urlify(self.title) 
0

Không hẳn câu trả lời của bạn, nhưng hãy để tôi giới thiệu ftfy (Fix chữ For You) mà sửa chữa một loạt các unicode nhỏ và các vấn đề html thoát. Một cuộc chiến tôn giáo thực sự gây phiền nhiễu trong mã hóa Unicode là sự bất lực của UTF-8 để đối phó với các mã hóa ký tự một byte khác nhau như Latin-1. Thay vì chỉ "oh, đó phải là một nhân vật Latin đơn giản", bộ giải mã bị bối rối. Khi trình điều khiển cơ sở dữ liệu của bạn làm cho quan sát "oh, điều này phù hợp", nó tạo ra tại fatwah.

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