Python 在alembic迁移中插入Unicode值

Python 在alembic迁移中插入Unicode值,python,python-2.7,unicode,sqlalchemy,alembic,Python,Python 2.7,Unicode,Sqlalchemy,Alembic,我正在做一个小项目,涉及多种货币的会计核算。在开发过程中,我决定使用alembic从直接的DB设置迁移到DB迁移。在一些迁移中,我需要用乌克兰语显示的初始货币填充DB 我的问题是,从alembic迁移脚本填充的数据以某种未知的编码保存,因此我无法在应用程序中使用它(这期望是人类可读的)。我的设置和脚本如下: from petproject import app app.config.from_object(config.DevelopmentConfig) engine = create_en

我正在做一个小项目,涉及多种货币的会计核算。在开发过程中,我决定使用alembic从直接的DB设置迁移到DB迁移。在一些迁移中,我需要用乌克兰语显示的初始货币填充DB

我的问题是,从alembic迁移脚本填充的数据以某种未知的编码保存,因此我无法在应用程序中使用它(这期望是人类可读的)。我的设置和脚本如下:

from petproject import app

app.config.from_object(config.DevelopmentConfig)
engine = create_engine(app.config["DATABASE"]+"?charset=utf8",
                       convert_unicode=True, encoding="utf8", echo=False)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))

if len(db_session.query(Currency).all()) == 0:
  default_currency = Currency()
  default_currency.name = u"Гривня"
  default_currency.abbr = u"UAH"
  db_session.add(default_currency)
  db_session.commit()
alembic.ini

...
sqlalchemy.url = mysql+pymysql://defaultuser:defaultpwd@localhost/petdb
...
alembic/versions/f433ab2a814\u adding\u currency.py

from alembic import op

# -*- coding: utf-8 -*-
"""Adding currency

Revision ID: f433ab2a814
Revises: 49538bba2220
Create Date: 2016-03-08 13:50:35.369021

"""

# revision identifiers, used by Alembic.
revision = 'f433ab2a814'
down_revision = '1c0b47263c82'
branch_labels = None
depends_on = None

def upgrade():
  op.create_table(
              'currency',
              Column('id', Integer, primary_key=True),
              Column('name', Unicode(120), nullable=False),
              Column('abbr', String(3), nullable=False)
          )
  op.execute(u'INSERT INTO currency SET name="{}", abbr="{}";'.format(u"Гривня", "UAH"))
从mysql客户端或mysql workbench中检查表
currency
,显示为:

mysql> SELECT * FROM currency;
+----+----------------------------+------+
| id | name                       | abbr |
+----+----------------------------+------+
|  1 | Ð“Ñ€Ð¸Ð²Ð½Ñ                | UAH  |
+----+----------------------------+------+
预期结果是:

mysql> SELECT * FROM currency;
+----+----------------------------+------+
| id | name                       | abbr |
+----+----------------------------+------+
|  1 | Гривня                     | UAH  |
+----+----------------------------+------+
从我的应用程序中,我已将此值设置为:

from petproject import app

app.config.from_object(config.DevelopmentConfig)
engine = create_engine(app.config["DATABASE"]+"?charset=utf8",
                       convert_unicode=True, encoding="utf8", echo=False)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))

if len(db_session.query(Currency).all()) == 0:
  default_currency = Currency()
  default_currency.name = u"Гривня"
  default_currency.abbr = u"UAH"
  db_session.add(default_currency)
  db_session.commit()

所以我想知道如何在迁移时插入初始Unicode值,这些值将以正确的编码存储。我遗漏了什么吗?

经过更深入的分析,我发现MySQL将所有数据都保存在“windows-1252”编码中。MySQL手册(第“”节)对此问题的说明如下:

latin1是默认字符集。MySQL的latin1与Windows cp1252字符集相同

看起来要么MySQL忽略了我假设为“utf-8”的字符集客户端,要么SQLAlchemy/alembic没有通知服务器将数据接受为“utf-8”编码数据。不幸的是,无法在
alembic.ini
中设置推荐选项“?charset=utf8”

为了以正确的编码接受和保存数据,我通过调用
op.execute('set NAMES utf8')手动设置字符集。因此,完整的代码如下所示:

def upgrade():
  op.create_table(
              'currency',
              Column('id', Integer, primary_key=True),
              Column('name', Unicode(120), nullable=False),
              Column('abbr', String(3), nullable=False)
          )
  op.execute('SET NAMES utf8')
  op.execute(u'INSERT INTO currency SET name="{}", abbr="{}";'.format(u"Гривня", "UAH"))
结果如预期:

mysql> SELECT * FROM currency;
+----+----------------------------+------+
| id | name                       | abbr |
+----+----------------------------+------+
|  1 | Гривня                     | UAH  |
+----+----------------------------+------+

是否将(服务器、数据库、表或列上的)设置为UTF-8排序规则?是。mysql>显示创建表货币;|表|创建表+------------------+-------------------------------------------+|货币|创建表
currency
id
int(11)非空自动增量,
name
varchar(120)COLLATE utf8\U unicode\U ci NOT NULL,
abbr
varchar(3)COLLATE utf8\U unicode\U ci NOT NULL,主键(
id
)引擎=InnoDB自动增量=4默认字符集=utf8 COLLATE=utf8\U unicode\U ci|