【问题标题】:Python MySQL UTF-8 encoding differs depending on order of executionPython MySQL UTF-8 编码因执行顺序而异
【发布时间】:2012-11-12 20:57:28
【问题描述】:

我最近继承了一个 python 项目,但我遇到了一些难以解释的行为。

代码有两个部分,可以将文件导入数据库,也可以将数据库转储到输出文件。导入看起来像这样:

def importStuff(self):
    mysqlimport_args = ['mysqlimport', '--host='+self.host, '--user='+self.username, '--password='+self.password, '--fields-terminated-by=|', '--lines-terminated-by=\n', '--replace', '--local', self.database, filename, '-v']
    output = check_output(mysqlimport_args)

转储看起来像这样:

def getStuff(self):
    db = MySQLdb.connect(self.host, self.username, self.password, self.database)
    cursor = db.cursor()
    sql = 'SELECT somestuff'
    cursor.execute(sql)
    records = cursor.fetchall()
    cursor.close()
    db.close()
    return records

def toCsv(self, records, csvfile):
    f = open(csvfile, 'wb')
    writer = csv.writer(f, quoting=csv.QUOTE_ALL)
    writer.writerow(['StuffId'])
    count = 1
    for record in records:
        writer.writerow([record[0]])

    f.close()

好吧,这不是你见过的最漂亮的蟒蛇(欢迎使用风格 cmets,因为我很想了解更多信息),但这似乎是合理的。

但是,我收到了消费者的投诉,说我的输出不是 UTF-8(顺便说一下,mysql 表使用的是 utf8 编码)。如果程序像这样执行,这就是我迷路的地方:

importStuff(...)

getStuff(...)

toCsv(...)

那么输出文件似乎不是有效的 utf-8。当我将执行分为两个不同的步骤时

importStuff(...)

然后在另一个文件中

getStuff(...)

toCsv(...)

我的输出突然显示为有效的 utf-8。除了我有一个解决办法之外,我似乎无法解释这种行为。谁能阐明我在这里做错了什么?还是我可以提供更多信息来说明发生了什么?

谢谢。

(python 2.7 以防万一)

编辑:根据要求提供更多代码。我做了一些小的调整来保护像我公司这样的无辜者,但它或多或少在这里:

def main():

    dbutil = DbUtil(config.DB_HOST, config.DB_DATABASE, config.DB_USERNAME, config.DB_PASSWORD)
    if(args.import):
        logger.info('Option: --import')

        try:
            dbutil.mysqlimport(AcConfig.DB_FUND_TABLE)
        except Exception, e:
            logger.warn("Error occured at mysqlimport. Error is %s" % (e.message))

    if(args.db2csv):
        try:
            logger.info('Option: --db2csv')
            records = dbutil.getStuff()
            fileutil.toCsv(records, csvfile)
        except Exception, e:
            logger.warn("Error Occured at db2csv. Message:%s" %(e.message))

main()

就是这样。它真的很短,这使得这一点变得不那么明显。

输出我不确定如何忠实地表示,它看起来像这样:

"F0NR006F8F"

在我看来,它们都或多或少像 ASCII 字符,所以我不确定它们会造成什么问题。也许我从错误的角度接近这个问题,我目前依靠我的文本编辑器对文件编码的最佳猜测。我不确定如何最好地检测哪个字符导致它停止读取我的文件作为 utf-8。

【问题讨论】:

  • 您能否提供两个不同代码段的示例,以及它们产生的两种不同结果?
  • 我认为还有一些其他问题你没有解决。您注意到的差异不应导致编码更改。
  • 可能重复:Writing UTF-8 String to MySQL with Python。我相信您需要:MySQLdb.connect 调用中的MySQLdb.connect(use_unicode=True, charset='utf8') 参数(use_unicode=True 不是绝对必要的,如果charset='utf8' 是隐含的)。
  • @PedroRomano 我尝试添加该标志,但我有同样的问题,也许我需要从不同的方向来解决这个问题。有没有办法可以尝试确定编辑告诉我的确切字符不是 utf-8?
  • @Dio:这只是一个猜测。 getStuff() 可能会返回 unicode 对象。 Python2 csv 模块 does not support unicode input(见注)。因此,您必须自己对行值进行编码。如果我的猜测是正确的,那就试试writer.writerow([record[0].encode('utf-8')])

标签: python mysql


【解决方案1】:

有史以来最愚蠢的答案。输入数据不是 UTF-8 格式。有人通过编写另一个存储过程来解决这个问题,该存储过程会定期调用以将非 utf-8 字符转换为 utf-8。在我把我的代码分成两个文件并分别运行它们的时间里,工作运行了。它只是碰巧以这种方式运行了 4-5 次,我尝试了它导致我的错误结论。我现在正在更改读取过程以适应非 utf-8 输入源,因此我没有隐藏在系统中的奇怪竞争条件。很抱歉带领大家参加这场鹅追逐。

【讨论】:

    猜你喜欢
    • 2014-04-09
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 2010-11-03
    • 2019-06-30
    • 2013-09-01
    • 1970-01-01
    • 2021-04-04
    相关资源
    最近更新 更多