Python insere dois pontos em um número decimal do Access via pyodbc
Estou tendo omesmo problema que esse cara e possivelmenteesse cara, mas eu estou por perto para compartilhar algum código e responder a perguntas!
Eu tenho algum código em um trabalho em lotes que lê campos de um banco de dados do Microsoft Access via pyodbc e prepara a saída para exibição.
Aqui está um trecho. Observe a afirmação.
def format_currency(amount):
if amount is None:
return ""
else:
result = "$%.2f" % amount
assert ":" not in result, (
"That's weird. The value %r of class %s is represented as %s" %
(amount, amount.__class__, result))
return result
Quando eu o executo, ele processa com sucesso 100.000 linhas e depois falha:
AssertionError: That's weird. The value Decimal('54871.0000') of class <class
'decimal.Decimal'> is represented as $54870.:0
Observe o cólon aberrante. Ocorre raramente - cerca de uma vez em 300.000 registros.
Quando tento isolá-lo, claro que funciona.
from decimal import Decimal
print "$%.2f" % Decimal('54871.0000')
$ 54871,00
O tipo do campo no Access é:
Tipo de dados: moedaCasas decimais: 2Máscara de entrada:Valor padrão:Regra de validação:Alinhamento de texto: geralMinha vaga suspeita de apontar o dedo com base em evidências insuficientes: pyodbc está cutucando com os internos do Decimal, talvez confundido por uma corrupção do Access. Como @ecatmuraponta:
':' é '9' + 1 em ASCII
Alguém viu isso e resolveu?
Versões:
Python 2.7.4pyodbc 3.0.6 (mais recente)Acessar 2010Windows 7Cavando mais:
odecimal
módulo é implementado em Python. Da minha leitura, os valores são descritos por quatro atributos:_exp
, _int
, _sign
, _is_special
Suspeitando de corrupção, imprimi os valores desses campos.
Surpreendentemente, paraambos o defeituoso e a versão de trabalho, recebo:
_exp: -4
_int: 548710000
_sign: 0
_is_special: False
Isso é estranho.
Nodecimal
módulo, o__float__
função é definida de forma bastante simples:
def __float__(self):
"""Float representation."""
return float(str(self))
Mas quando faço isso com os dados ruins:
print "Str", str(amount)
print "Float", float(amount)
Eu recebo:
Str 54871.0000
Float 54870 .:
Quanto mais eu aprendo, menos estranhonão faz pegue.