在alembic迁移中插入Unicode值

2024-06-16 10:15:34 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

亚历姆比奇.ini

...
sqlalchemy.url = mysql+pymysql://defaultuser:defaultpwd@localhost/petdb
...

alembic/versions/f433ab2a814添加_货币.py

^{pr2}$

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值,这些值将以正确的编码存储。我错过什么了吗?在


Tags: nameconfigfalseappdefaultdbsessionmysql
1条回答
网友
1楼 · 发布于 2024-06-16 10:15:34

经过更广泛的分析,我发现MySQL将所有数据保存在“windows-1252”编码中。MySQL手册(第“West European Character Sets”部分)将此问题描述为:

latin1 is the default character set. MySQL's latin1 is the same as the Windows cp1252 character set.

看起来可能是MySQL忽略了character_set_client,我假设它是'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"))

结果如期而至:

^{pr2}$

相关问题 更多 >