Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何配置sqlalchemy以正确存储表情符号?_Python_Mysql_Sqlalchemy - Fatal编程技术网

Python 如何配置sqlalchemy以正确存储表情符号?

Python 如何配置sqlalchemy以正确存储表情符号?,python,mysql,sqlalchemy,Python,Mysql,Sqlalchemy,使用sqlalchemy 0.9.7,我尝试将表情符号存储到启用utf8mb4的MySQL 5.5中。然而,由于某种原因,sqlalchemy正在杀死我的表情符号,我不知道为什么。在试图通过sqlalchemy保存数据之前,我可以在对象中看到表情符号。保存后,将抛出一个错误,表情符号将呈现为 错误如下。注意,它被输出type(post.message)和post.message的调试消息包围 ----------------------------------------------------

使用sqlalchemy 0.9.7,我尝试将表情符号存储到启用utf8mb4的MySQL 5.5中。然而,由于某种原因,sqlalchemy正在杀死我的表情符号,我不知道为什么。在试图通过sqlalchemy保存数据之前,我可以在对象中看到表情符号。保存后,将抛出一个错误,表情符号将呈现为

错误如下。注意,它被输出
type(post.message)
post.message
的调试消息包围

--------------------------------------------------------------------------------
DEBUG in __init__ [/mnt/hgfs/crw/dev/hyper/hyper/blueprint/chat/__init__.py:274]:
<type 'unicode'>
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
DEBUG in __init__ [/mnt/hgfs/crw/dev/hyper/hyper/blueprint/chat/__init__.py:275]:
Here is the solution that worked for me. 
set_unicode
gets called the first time a connection enters the connection pool and only gets called once.
SET NAMES
basically fixes the entire pipeline from your code to the database storage to ensure the correct UTF-8 charset (
utf8mb4
) is used. As long as
utf8mb4
is ensured end to end, emojis should be stored / rendered fine as they are just regular unicode characters outside of BMP (Basic Multilingual Plane), which unfortunately MySQL decided that it was a good idea to only implement 3-byte Unicode implementation for BMP as the
unicode
charset.

See SQLAlchemy events reference for other relevant event hooks that you can tap into to do connection by connection configuration tweaks.

import logging
from sqlalchemy import event

logger = logging.getLogger(__name__)     

@event.listens_for(Pool, "connect")
def set_unicode(dbapi_conn, conn_record):
    cursor = dbapi_conn.cursor()
    try:
        cursor.execute("SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'")
    except Exception as e:
        logger.debug(e)
--------------------------------------------------------------------------------
调试在\uuuu init\uuuu[/mnt/hgfs/crw/dev/hyper/hyper/blueprint/chat/\uuuuu init\uuuuuu.py:274]:
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
调试在\uuuu init\uuuu[/mnt/hgfs/crw/dev/hyper/hyper/blueprint/chat/\uuuuu init\uuuuu.py:275]:

这是对我有效的解决方案
set_unicode
在连接第一次进入连接池时被调用,并且只被调用一次<代码>集名称基本上修复了从代码到数据库存储的整个管道,以确保使用正确的UTF-8字符集(
utf8mb4
)。只要确保端到端的
utf8mb4
,emojis就应该存储/呈现良好,因为它们只是BMP()之外的常规unicode字符,不幸的是,MySQL决定只将BMP的3字节unicode实现作为
unicode
字符集是个好主意

有关其他相关事件挂钩的信息,请参阅,这些挂钩可用于逐个连接配置调整


更新:关于连接字符串中的额外选项,我更喜欢显式地指定
charset=utf8mb4
,因为我的环境的默认字符集是
utf8
(这就是emoji无法正确编码的原因),但是千万不要指定
使用unicode=0
,除非您运行的是python 2.x,并且正如您在链接中指出的那样,性能是一个瓶颈。

下面是我如何让emojis等工作的。我使用的是Python 3.5/Flask/Flask SQLAlchemy

注意:此修复程序假定您在开发阶段已经足够早,可以通过运行
db.drop\u all()
db.create\u all()
来重新创建数据库

  • 按照中的建议,打开数据库控制台并运行
    alterdatabase\u name CHARACTER SET=utf8mb4 COLLATE=utf8mb4\u unicode\u ci

  • 按照中的建议,将
    ?charset=utf8mb4
    添加到
    SQLALCHEMY\u数据库\u URI
    字符串的末尾

    • 之前:
      mysql+mysqlconnector://{username}:{password}@{hostname}/{databasename}
    • 之后:
      mysql+mysqlconnector://{username}:{password}@{hostname}/{databasename}?charset=utf8mb4
  • 现在只需重新运行
    db.drop\u all()
    db.create\u all()


  • 一个表情符号变成了4个问号?在某个阶段闻起来像拉丁语1,可能是您删除的?charset=utf8。无论如何,这可能应该是utf8mb4。正如@RickJames指出的,一个有趣的观察结果是,如果您看到一个问号,这意味着它正确地存储为4字节UTF-8字符串,但当前连接使用的是
    unicode
    字符集。切换到
    utf8mb4
    会让它看起来不错。f“mysql://{USERNAME}:{PW}@{HOST}:{PORT}/{DB_NAME}?charset=utf8mb4”