'ascii' codec can't decode byte
Por uma semana lutei contra esse erro procurando em muitos sites e fóruns uma solução. O que me ocorrei era que eu lia a partir de um zip os dados a serem inseridos em uma tabela, e o nome da tabela era retirado a partir do nome do arquivo em questão.
Para entender todo o cenário, vou tentar explicar usando meus os códigos:
def populateTable(data, tableName):
try:
lines = data.splitlines()
part1 = "insert into %s (" % tableName
for line in lines:
lineFields = ""
lineValues = ""
if len(line) == 0:
continue
elif len(line.strip()) == 0:
continue
for it1, it2 in self.table.iteritems():
lineFields += it1 + ","
if it2["tipo"] == "int":
lineValues += line[int(it2["inicio"])-1:int(it2["fim"])] + ","
else:
lineValues += "\"" + line[int(it2["inicio"])-1:int(it2["fim"])] + "\","
query = "insert into %s (%s) values (%s);" % (tableName, lineFields[:-1].lower(), lineValues[:-1])
self.executeQuery(query)
except ValueError as error:
raise
zf = zipfile.ZipFile(self.zipFile) # carrega o arquivo zip com todos os txts que precisarei ler e inserir no mysql
for filename in zf.namelist():
dataToInsert = zf.read(filename)
populateTable(dataToInsert, filename[:-4]) # retiro o .txt para sobrar apenas o que será o nome da tabela
Quando eu tentava concatenar o nome tabela (tableName) com os dados retirados desse arquivo, o python me dava o seguinte erro:
__main__:run.py:185 'ascii' codec can't decode byte 0xea in position 35: ordinal not in range(128)
Traceback (most recent call last):
UnicodeDecodeError: 'ascii' codec can't decode byte 0xea in position 35: ordinal not in range(128)
Quando eu tentava concatenar o nome do arquivo com os dados retirados desse arquivo, o python me dava o seguinte erro:
__main__:run.py:185 'ascii' codec can't decode byte 0xea in position 35: ordinal not in range(128)
Traceback (most recent call last):
UnicodeDecodeError: 'ascii' codec can't decode byte 0xea in position 35: ordinal not in range(128)
Após várias pesquisas, encontrei o erro, usando o seguinte teste. Procurei saber quais os tipos de objetos cada variável pertencia.
print type(tableName), repr(tableName)
<type 'unicode'> u' ... '
print type(lineValues), repr(lineValues)
<type 'str'> ' ... '
Assim, vi que a variável 'tableName' era do tipo 'unicode', e a 'lineValues' era do tipo 'str'. O problema era na hora de concatenar as duas variáveis.
Para resolver foi simples, apenas fiz um cast para string na variável 'tableName' e tudo deu certo!
query = "insert into %s (%s) values (%s);" % (str(tableName), lineFields[:-1].lower(), lineValues[:-1])