我有一个MySQL设置,其中所有表/字段和字符集设置都是UTF-8
,但SqlAlchemy的连接除外。
我最近将连接字符集更改为UTF-8
,以便在任何地方使用UTF-8
。
更改此设置时,DB中的旧值会出错,例如:
Björn => Björn
这没问题,我只是使用python中的encode方法收集值并对它们进行编码,然后再将它们重新放入。
当我尝试转换设置更改后插入的值时,会出现问题,这些值已经正确。
有没有一种好方法可以确定我是否应该对值进行编码?
答案 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范围之外,您还需要包含以下规则:
3个UTF-8字节数据涵盖BMP的其余部分,您不太可能在此之外进行编码。如果您在此之外进行编码,请查找:
如果所有这些条件匹配,则可能具有UTF-8字符串,但您不能100%确定。如果其中任何一个不匹配,你肯定有一个Latin-1字符串。但是,拉丁语-1代码点C2-DF不太可能跟随代码点80-BF,因为后者的大多数是控制代码或更深奥的变音符号。也许你可以通过寻找多个2字节UTF-8序列来进一步缩小范围,以提高你的置信度。
因此,总而言之(tl; dr):通过查看多字节序列,您可以找到大多数 Latin-1编码字符串。如果它们不属于严格的UTF-8标准,那么您手上就有一个Latin-1字符串。