Python MySQL UTF-8编码因执行顺序而异
我最近继承了一个python项目,我有一些行为我很难解释 该代码有两个部分,可以将文件导入数据库,也可以将数据库转储到输出文件。导入内容如下所示:Python MySQL UTF-8编码因执行顺序而异,python,mysql,Python,Mysql,我最近继承了一个python项目,我有一些行为我很难解释 该代码有两个部分,可以将文件导入数据库,也可以将数据库转储到输出文件。导入内容如下所示: def importStuff(self): mysqlimport_args = ['mysqlimport', '--host='+self.host, '--user='+self.username, '--password='+self.password, '--fields-terminated-by=|', '--lines-te
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()
importStuff(...)
getStuff(...)
toCsv(...)
"F0NR006F8F"
转储如下所示:
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()
importStuff(...)
getStuff(...)
toCsv(...)
"F0NR006F8F"
好吧,这不是你见过的最漂亮的python(欢迎风格评论,因为我想了解更多),但它似乎是合理的
但是,我收到一位消费者的投诉,说我的输出不是UTF-8格式(顺便说一句,mysql表使用utf8编码)。这里是我迷路的地方,如果程序像这样执行:
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()
importStuff(...)
getStuff(...)
toCsv(...)
"F0NR006F8F"
那么输出文件似乎不是有效的utf-8。当我将执行分为两个不同的步骤时
importStuff(...)
然后在另一个文件中
getStuff(...)
toCsv(...)
突然,我的输出显示为有效的utf-8。除了我的工作之外,我似乎无法解释这种行为。有人能解释一下我做错了什么吗?或者我能提供更多的信息来澄清发生了什么
谢谢
(Python2.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()
就这样。它很短,这使得它不那么明显
我不确定如何忠实地表示输出,它看起来像这样:
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()
importStuff(...)
getStuff(...)
toCsv(...)
"F0NR006F8F"
在我看来,它们或多或少都像ASCII字符,所以我不确定它们会造成什么问题。也许我从错误的角度来处理这个问题,我目前依赖于我的文本编辑器对文件编码的最佳猜测。我不知道如何才能最好地检测出哪个字符导致它停止以utf-8格式读取我的文件。这是有史以来最愚蠢的回答。输入数据不在UTF-8中。有人通过编写另一个存储过程来解决这个问题,该存储过程将定期调用以将非utf-8字符转换为utf-8。在我将代码分解成两个文件并分别运行它们的过程中,作业运行了。我尝试了4-5次,结果却得出了错误的结论。我现在正在更改读取过程以适应非utf-8输入源,这样系统中就不会隐藏奇怪的竞争条件。很抱歉把你们都带到这个goosechase上 你能提供一个两段不同代码的例子,以及它们产生的两种不同结果吗?我想还有一些其他的问题你没有解决。您注意到的差异不应导致编码更改。可能的重复项:。我相信您需要:
MySQLdb.connect(在您的MySQLdb.connect
调用中使用unicode=True,charset='utf8')
参数(use\unicode=True
不是严格必需的,如果charset='utf8'
则是隐式的)。@PedroRomano我尝试添加该标志,但我也遇到了同样的问题,也许我需要从另一个方向来看这个问题。有什么方法可以让我确定我的编辑告诉我的确切角色不是utf-8吗?@Dio:这只是一个猜测getStuff()
可能正在返回unicode
对象。Python2csv
模块(参见注释)。因此,您必须自己对行值进行编码。如果我的猜测是正确的,那么请尝试writer.writerow([record[0].encode('utf-8'))
。