6

Flask、SQLAlchemy、および WTForms を使用する Web アプリケーションと、必要な Flask 拡張機能を使用して、すべてを機能させています。MySQL はutf8_binすべてのテーブルと列に使用しています。

いくつかの漢字を挿入し、phpMyAdmin はそれらを正しく表示しますが、ページを開こうとするたびに次の例外が発生します。

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

表示したいフィールドを表示する必要があることは理解decode('utf8')していますが、これは SQLAlchemy によって処理されるべきではありませんか?

これを機能させる唯一の方法は、結果のリストを繰り返し処理し、次のようなことを行うことでした。

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

しかし、明らかにこれは手動で行う必要はありません。私は何が欠けていますか?

更新: 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))

更新: スタック トレース

`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)`

更新: プロジェクト リポジトリの URL:

https://github.com/ruipacheco/fruitshow

4

4 に答える 4

4

問題は、私が使用している MySQL ドライバーにあります。

私はこの答えに従い、列の種類をからutf8_binに切り替えましたutf8_general_ci

于 2013-10-07T15:47:24.097 に答える
2

ModelsのSlugフィールドに関するちょっとした提案。

Webhelpers ( https://pypi.python.org/pypi/WebHelpers )というライブラリがあり、それをインポートすると、タイトルが自動的にスラッグに変換されます。

WebHelpersをインストールしてからurlifyをインポートします

from webhelpers.text import urlify
.
.
.
@property
def slug(self):
    return urlify(self.title)
于 2013-10-10T16:51:09.230 に答える
0

接続パラメーターに文字セットを設定すると、データベース内にある列から要求された形式のエンコードに列をトランスコードするように mysql に指示するだけです。データは引き続き MySQL とクライアントの間でバイトとして渡されます。sqlalchemyつまり、 「この特定の」データが Unicode データ (接続のエンコーディング) であることを伝える必要があります。ほとんどの列で、Unicodeこの目的に役立つ を使用しています。注目に値するのはbodyで、タイプはTextです。あなたはおそらくしたいUnicodeText、またはText(convert_unicode=True)

于 2013-10-06T01:53:47.950 に答える
0

あなたの答えではありませんが、小さな unicode と html エスケープの問題を修正するftfy (Fix Text For You) をお勧めします。Unicode エンコーディングにおける本当に厄介な宗教戦争の 1 つは、UTF-8 が Latin-1 などのさまざまな 1 バイト文字エンコーディングを処理できないことです。「ああ、それは単純なラテン文字に違いない」というだけでなく、デコーダーは混乱します。データベースドライバーが「ああ、これは合っている」という観測を行うと、fatwah に作成されます。

于 2013-10-13T19:45:27.383 に答える