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: Allgemein

Mein 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 7

Weiter 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.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage