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

时间:2014-07-29 07:51:13

标签: python mysql sqlalchemy

使用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]:

--------------------------------------------------------------------------------
/mnt/hgfs/crw/dev/hyper/env/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py:436: Warning: Incorrect string value: '\xF0\x9F\x98\x83' for column 'message' at row 1
  cursor.execute(statement, parameters)
--------------------------------------------------------------------------------
DEBUG in __init__ [/mnt/hgfs/crw/dev/hyper/hyper/blueprint/chat/__init__.py:277]:
<type 'unicode'>
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
DEBUG in __init__ [/mnt/hgfs/crw/dev/hyper/hyper/blueprint/chat/__init__.py:278]:
????
--------------------------------------------------------------------------------

我的代码如下:

Base = declarative_base()

post = Table('post', Base.metadata,
        Column("id", Integer, primary_key=True),
        Column("message", UnicodeText),
        Column("created_at", DateTime),
        Column("updated_at", DateTime),
    )

mapper(Post, post)

我需要做任何其他设置才能完成这项工作吗?

更新:如果我执行以下操作:

Base = declarative_base()

post = Table('post', Base.metadata,
        Column("id", Integer, primary_key=True),
        Column("message", UnicodeText),
        Column("created_at", DateTime),
        Column("updated_at", DateTime),
        mysql_engine='InnoDB',
        mysql_charset='utf8mb4'
    )

mapper(Post, post)

我得到以下内容:

--------------------------------------------------------------------------------
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]:

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
DEBUG in __init__ [/mnt/hgfs/crw/dev/hyper/hyper/blueprint/chat/__init__.py:277]:
<type 'unicode'>
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
DEBUG in __init__ [/mnt/hgfs/crw/dev/hyper/hyper/blueprint/chat/__init__.py:278]:
????
--------------------------------------------------------------------------------

没有错误,但它仍在消灭表情符号。发生了什么事?!

更新2:

从以下位置更改要调用的数据库URI:

mysql+mysqldb://user:pass@localhost/datab?charset=utf8

mysql+mysqldb://user:pass@localhost/datab

修正了问题。当我尝试使用charset=utf8mb4&use_unicode=0时,sqlalchemy引发了错误。但那是明智的吗?根据{{​​3}},它不是!非常喜欢这个解决方案的任何反馈。

1 个答案:

答案 0 :(得分:2)

以下是我如何使用表情符号等工作。我使用的是Python 3.5 / Flask / Flask-SQLAlchemy。

注意:此修复程序假定您在开发过程中尽早通过运行db.drop_all()db.create_all()来重新创建数据库。

  1. 根据this guide的建议,打开数据库控制台并运行ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

  2. 根据this answer的建议,将?charset=utf8mb4添加到SQLALCHEMY_DATABASE_URI字符串的末尾。

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