Python fügt einen Doppelpunkt in eine Dezimalzahl von Access via pyodbc ein
Ich habe diedas gleiche Problem wie dieser Typ und möglicherweisedieser Typ, aber ich bin da, um Code zu teilen und auf Fragen zu antworten!
Ich habe Code in einem Stapeljob, der Felder aus einer Microsoft Access-Datenbank über pyodbc liest und die Ausgabe für die Anzeige vorbereitet.
Hier ist ein Ausschnitt. Beachten Sie die Behauptung.
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
Wenn ich es ausführe, verarbeitet es erfolgreich 100.000 Zeilen und schlägt dann fehl:
AssertionError: That's weird. The value Decimal('54871.0000') of class <class
'decimal.Decimal'> is represented as $54870.:0
Beachten Sie den abweichenden Doppelpunkt. Es kommt selten vor - etwa einmal in 300.000 Datensätzen.
Wenn ich versuche, es zu isolieren, funktioniert es natürlich.
from decimal import Decimal
print "$%.2f" % Decimal('54871.0000')
54871,00 USD
Der Feldtyp in Access ist:
Datentyp: WährungNachkommastellen: 2Eingabemaske:Standardwert:Validierungsregel:Text ausrichten: AllgemeinMein vager Fingerzeigverdacht basiert auf unzureichenden Beweisen: pyodbc stochert mit den Interna von Decimal, möglicherweise verwirrt durch eine Access-Korruption. Als @ecatmurweist darauf hin:
':' ist '9' + 1 in ASCII
Hat das jemand gesehen und gelöst?
Versionen:
Python 2.7.4pyodbc 3.0.6 (aktuell)Access 2010Windows 7Weiter graben:
Dasdecimal
Modul ist in Python implementiert. Nach meiner Lektüre werden die Werte durch vier Attribute beschrieben:_exp
, _int
, _sign
, _is_special
Bei dem Verdacht auf Korruption habe ich die Werte dieser Felder ausgedruckt.
Überraschenderweise fürbeide Die fehlerhafte und funktionierende Version bekomme ich:
_exp: -4
_int: 548710000
_sign: 0
_is_special: False
Das ist komisch.
In demdecimal
Modul, das__float__
Funktion ist ziemlich einfach definiert:
def __float__(self):
"""Float representation."""
return float(str(self))
Aber wenn ich das mit den schlechten Daten mache:
print "Str", str(amount)
print "Float", float(amount)
Ich bekomme:
Str 54871.0000
Schwimmer 54870 .:
Je mehr ich lerne, desto weniger komisch ist esnicht erhalten.