更改连接字符集时如何确定是否应编码?

时间:2012-08-14 09:02:20

标签: python mysql encoding sqlalchemy

我有一个MySQL设置,其中所有表/字段和字符集设置都是UTF-8,但SqlAlchemy的连接除外。

我最近将连接字符集更改为UTF-8,以便在任何地方使用UTF-8

更改此设置时,DB中的旧值会出错,例如:

Björn => Björn

这没问题,我只是使用python中的encode方法收集值并对它们进行编码,然后再将它们重新放入。

当我尝试转换设置更改后插入的值时,会出现问题,这些值已经正确。

有没有一种好方法可以确定我是否应该对值进行编码?

1 个答案:

答案 0 :(得分:0)

您的旧编码可能是拉丁语1?

你可能可以通过查看连续的字节来检测字符串是用Latin-1而不是UTF-8编码的。 UTF-8标准有distinctive codepage layout我们可以用来检测一段文本是用Latin-1还是UTF-8编码的:

  • 00-7F范围内的任何字节都是安全的,当然,这些是ASCII值,这些代码点在两种编码之间匹配。这里没有帮助,没有必要帮助。

  • UTF-8编码中的字节C0,C1和F5-FF是非法。任何包含这些字符串的字符串都必须是Latin-1编码。

  • C2-DF 范围内的字节必须后跟80-BF范围内的字节。如果您有任何两个不匹配的字节,您可能手上有一个Latin-1编码的字符串。

如果您编写的所有内容都是Latin-1字符(最多为Unicode代码点255),您可以在此处停止;包含E0-FF范围内字节的任何内容都是旧的Latin-1数据。

如果您 在您切换后添加了UTF-8中的数据,那么在Latin-1范围之外,您还需要包含以下规则:

  • E0-EF范围内的字节标记为3字节的UTF-8字符。接下来的两个字节必须再次落在80-BF的范围内。

3个UTF-8字节数据涵盖BMP的其余部分,您不太可能在此之外进行编码。如果您在此之外进行编码,请查找:

  • 在F0-F4范围内的字节必须紧跟在80-BF范围内的3个字节。

如果所有这些条件匹配,则可能具有UTF-8字符串,但您不能100%确定。如果其中任何一个匹配,你肯定有一个Latin-1字符串。但是,拉丁语-1代码点C2-DF不太可能跟随代码点80-BF,因为后者的大多数是控制代码或更深奥的变音符号。也许你可以通过寻找多个2字节UTF-8序列来进一步缩小范围,以提高你的置信度。

因此,总而言之(tl; dr):通过查看多字节序列,您可以找到大多数 Latin-1编码字符串。如果它们不属于严格的UTF-8标准,那么您手上就有一个Latin-1字符串。