【问题标题】:Flask_SQLAlchemy, MySQL, store Swedish characters å, ä, ö?Flask_SQLAlchemy,MySQL,存储瑞典语字符å、ä、ö?
【发布时间】:2017-04-04 02:55:30
【问题描述】:

我无法通过使用 Flask_SQLAlchemy 在 MySQL 中存储瑞典语字符 :( 我已经尝试找到一个解决方案一周了,我真的需要帮助,因为感觉我已经走到了死胡同。我想可能是我的工具的版本兼容性有问题,但我不希望如此!我正在尝试使用 Flask、Flask_SQLAlchemy 和 MySQL (5.5.3) 构建网站。如果无法解决,我正在考虑将 Flask_SQLAlchemy 更改为其他内容.. (我上了一门编程课程(Python),其余的都是自己思考的,所以如果你的答案尽可能详细,我会很高兴,也非常感谢任何建议!)

(competeEnv) C:\>conda list
 # packages in environment at C:\Users\MyName\Anaconda3.1\envs\competeEnv:
 #
click                     6.6                      py27_0
flask                     0.11.1                   py27_0
Flask-SQLAlchemy          2.1                       <pip>
itsdangerous              0.24                     py27_0
jinja2                    2.8                      py27_1
markupsafe                0.23                     py27_2
mysql-python              1.2.5                    py27_0
pip                       9.0.1                    py27_0
python                    2.7.12                        0
setuptools                27.2.0                   py27_1
sqlalchemy                1.1.4                    py27_0
vs2008_runtime            9.00.30729.1                  2
werkzeug                  0.11.11                  py27_0
wheel                     0.29.0                   py27_0
(competeEnv) C:\>

这是 testAlchemy.py 文件中的代码

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:myPassword@myServer/firstdb'
app.config['SQLALCHEMY_ECHO'] = False
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
app.config['MYSQL_DATABASE_CHARSET'] = 'utf8mb4'
db = SQLAlchemy(app)


class Users(db.Model):
    __tablename__='users'
    id=db.Column('iduser', db.Integer, primary_key=True)
    name=db.Column('column_name', db.String(193))

    def __init__(self, name):
        self.name=name

    def __repr__(self):
        return self.name

db.create_all()
db.session.commit()

president1=Users('Obama')
president2=Users('Trump')
db.session.add(president1)
db.session.add(president2)
db.session.commit()

这里应该有一些提示..

(competeEnv) C:\Users\MyName\Anaconda3.1\envs>python
Python 2.7.12 |Continuum Analytics, Inc.| (default, Jun 29 2016, 11:07:13)[MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://anaconda.org
>>> from testAlchemy import Users, db
>>> db.session.add(Users('Federer'))
>>> db.session.commit()
>>> Users.query.all()
[Obama, Trump, Federer]
>>> db.session.add(Users('ä'))
>>> db.session.commit()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\scoping.py", line 157, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\session.py", line 801, in commit
self.transaction.commit()
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\session.py", line 392, in commit
self._prepare_impl()
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\session.py", line 372, in _prepare_impl
self.session.flush()
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\session.py", line 2019, in flush
self._flush(objects)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\session.py", line 2137, in _flush
transaction.rollback(_capture_exception=True)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 60, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\session.py", line 2101, in _flush
flush_context.execute()
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 373, in execute
rec.execute(self)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 532, in execute
uow
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\persistence.py", line 174, in save_obj
mapper, table, insert)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\orm\persistence.py", line 800, in _emit_insert_statements
execute(statement, params)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\engine\base.py", line 914, in execute
return meth(self, multiparams, params)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\sql\elements.py", line 323, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\engine\base.py", line 1010, in _execute_clauseelement
compiled_sql, distilled_params
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\engine\base.py", line 1146, in _execute_context
context)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\engine\base.py", line 1341, in _handle_dbapi_exception
exc_info
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\util\compat.py", line 202, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\engine\base.py", line 1139, in _execute_context
context)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\sqlalchemy\engine\default.py", line 450, in do_execute
cursor.execute(statement, parameters)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\MySQLdb\cursors.py", line 205, in execute
self.errorhandler(self, exc, value)
File "C:\Users\MyName\Anaconda3.1\envs\competeEnv\lib\site-packages\MySQLdb\connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (1366, "Incorrect string value: '\\x84' for column 'column_name' at row 1") [SQL: u'INSERT INTO users (column_name) VALUES (%s)'] [parameters: ('\x84',)]
>>>

【问题讨论】:

  • 请不要使用 MySQL 5.5.3——它是一个预发布版本。 5.5.8 是 5.5 的第一个 GA。

标签: mysql flask flask-sqlalchemy mysql-python utf8mb4


【解决方案1】:

由于您使用的是 Python 2.7,因此您需要指定您的字符串包含 unicode。

>>> db.session.add(Users(u'ä'))

您还可以使用将来的导入将所有字符串视为 unicode。

from __future__ import unicode_literals

您也可以升级您的 Python 版本。 2.7 是最后一个将字符串视为字节而不是 unicode 的版本。

编辑

您还需要更新您的 __repr__ 以便它正确处理 unicode。

def __repr__(self):
    return self.name.decode('utf-8')

或您想使用的任何编码。

通常,您需要确保处理从 unicode 编码和解码到 unicode。我不能敦促您考虑使用更新版本的 Python。 Python 3 中最大的变化之一就是解决了这个问题。

【讨论】:

  • 成功将其添加到数据库中!太棒了,谢谢。但是,当我尝试检索它时,似乎存在相关问题.. >>> db.session.add(Users(u'ä')) >>> db.session.commit() >>> Users.query .all() [Obama, Trump, Obama, Trump, new, Traceback(最近一次通话最后):文件“”,第 1 行,在 UnicodeEncodeError: 'ascii' codec can't encode character u' \xe4' 在位置 0:序数不在范围内(128)
  • 谢谢!你似乎是对的。但我会说实话,因为这仍然是一个问题。 >>> Users.query.all() [Obama, Trump, new, new, Traceback(最近一次通话最后):文件“”,第 1 行,在 文件“C:\Users\MyName\ Anaconda3.1\envs\envNew\testAlchemy.py",第 22 行,在 repr 中 return self.name.decode('utf-8') File "C:\Users\MyName\Anaconda3.1 \envs\envNew\lib\encodings\utf_8.py",第 16 行,解码返回 codecs.utf_8_decode(input, errors, True) UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 0:序数不在范围内(128)
  • 关于我应该使用 python 3 的好主意,我认为,因为 sqlAlchemy 使用仅与 python 2.7 兼容的 MySQLdb (python-mySQL) ..不幸的是: (
  • SQLAlchemy 使用您告诉它使用的任何驱动程序。您可以使用适用于 Python 3 的 MySQL 驱动程序。
  • 感谢所有建议。但是,从 MySQL 中检索字符仍然存在问题。 “使用 Flask-Alchemy 从 MySQL 中检索 Ä、ê 等字符”link
【解决方案2】:

在使用UTF-8 字符时,尽量避免任何类型的编码/解码;这只是掩盖了真正的问题,这通常在某个配置中。

我对 sqlalchemy 的笔记:

db_url = sqlalchemy.engine.url.URL(drivername='mysql', host=foo.db_host,
    database=db_schema,
    query={ 'read_default_file' : foo.db_config, 'charset': 'utf8' })

json.dumps(mydict, ensure_ascii=False) avoids "\u...." strings.

https://docs.sqlalchemy.org/en/latest/dialects/mysql.html#mysql-unicode

Python 2.7 相当老了,请看这里与 3 的区别:

https://stackoverflow.com/a/40708131/1766831

utf8 的 Python 提示:http://mysql.rjweb.org/doc.php/charcoll#python

【讨论】:

    猜你喜欢
    • 2011-07-28
    • 2019-07-12
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多