2009-05-06 32 views
3

Ich verwende pyodbc, über Microsoft Jet, um auf die Daten in einer Microsoft Access 2003-Datenbank von einem Python-Programm zuzugreifen.PyODBC und Microsoft Access: Inkonsistente Ergebnisse von einfachen Abfrage

Die Microsoft Access-Datenbank stammt von einem Drittanbieter; Ich lese nur die Daten.

Ich habe im Allgemeinen Erfolg bei der Extraktion der Daten, die ich brauche, aber ich habe kürzlich einige Diskrepanzen festgestellt.

Ich habe es gekocht auf eine einfache Abfrage nach unten, von der Form:

SELECT field1 FROM table WHERE field1 = 601 AND field2 = 9067 

Ich habe die Feldnamen und Werte verschleiert aber wirklich, ist es nicht viel mehr trivial als das! Wenn ich die Abfrage in Access ausführe, gibt es einen Datensatz zurück.

Dann laufe ich es über Pyodbc, mit Code, der wie folgt aussieht:

connection = pyodbc.connect(connectionString) 
rows = connection.execute(queryString).fetchall() 

(Wieder ist es nicht viel mehr trivial als das bekommt!)

Der Wert von querystring wird geschnitten -und-eingefügt von der Arbeitsabfrage in Access, aber es gibt keine Datensätze zurück. Ich habe erwartet, dass es den gleichen Rekord zurückgibt.

Wenn ich die Abfrage ändern, um nach einem anderen Wert für Feld2, Bingo zu suchen, funktioniert es. Es sind nur einige Werte, die es ablehnt.

Also, bitte helfen Sie mir aus. Wo soll ich als nächstes diese Diskrepanz erklären? Wenn ich den Ergebnissen trivialer Anfragen nicht trauen kann, habe ich bei diesem Projekt keine Chance!

Update: Es wird noch einfacher! Die folgende Abfrage gibt verschiedene Zahlen ...

SELECT COUNT (*) FROM Tabelle

ich darüber nachzudenken, ob es zu irgendeiner Form von Caching und/oder unsachgemäßen Transaktionsmanagement von einer anderen Anwendung verwendet ist, die gelegentlich die Daten auffüllt .

+0

Sollten Sie ein Cursor-Objekt zum Ausführen der Abfragezeichenfolge dort haben? Fetchall würde dann am Cursor aufgerufen, um Zeilen zu erzeugen. Siehe http://code.google.com/p/pyodbc/wiki/Rows – barrowc

+0

@barrowc, Interessant. Ich habe das Fehlen eines cursor() -Aufrufs nicht bemerkt. Ich bin mir sicher, dass ich das irgendwo von einem Beispiel kopiert habe. Ich habe versucht, es wieder in [rows = connection.cursor(). Execute (queryString) .fetchall()] hinzuzufügen, aber es machte keinen Unterschied - anscheinend pyodbc ist verzeihender als die Python-DB-API-Spezifikation. – Oddthinking

Antwort

1

Das Problem wurde zwischen einem Upgrade auf Access 2007 und dem Herunterladen einer neuen Kopie der Datenbank von der Quelle gelöst. Ich weiß immer noch nicht, was die Ursache war, aber ich vermute eine Form der Indexbeschädigung.

1

Können Sie uns eine verschleierte Datenbank geben, die dieses Problem anzeigt? Das habe ich noch nie erlebt. Geben Sie zumindest die Tabellendefinitionen an - sind irgendwelche der Spalten schwebend oder dezimal?

+0

Ich habe Sie für den Vorschlag zur Überprüfung auf Floats gewählt. Gutes Denken, aber das ist nicht das Problem, wie die aktualisierte Version ohne WHERE-Klausel zeigt. Ich arbeite daran, wie Sie eine Tabelle Beschreibung von Access für Sie erhalten. – Oddthinking

1

Das klingt vielleicht dumm. Aber ...

Ist der Pfad zur tatsächlichen Datenbank & Verbindungszeichenfolge (DSN) auf dieselbe Dateiposition zeigen?

+0

Das ist ein vollkommen vernünftiger Vorschlag; Ich hoffe wirklich, dass es etwas so Triviales ist! Ich habe doppelt überprüft, und beide zeigen auf das gleiche Verzeichnis. Ich habe gesehen, Access 2003 verwirrt und scheinbar eine neuere MDB-Datei, die seit dem gelöscht wurde, zu öffnen, so frage ich mich immer noch, ob hier etwas Caching oder ähnliches passiert. – Oddthinking

+0

Ist die MDB-Datei in einem Netzwerkpfad, den Sie versuchen, mit einer Python-basierten Anwendung auf dem Computer zu verwenden? – shahkalpesh

1

Haben Sie das gleiche Problem mit anderen ODBC-Tools, zum Beispiel Query Tool? Sie können die ODBC-Ablaufverfolgung auch im ODBC-Verbindungs-Manager aktivieren. Ich habe keinen Zugang und weiß nicht, ob seine SQL-Befehle verfolgt werden, aber manchmal hilft es mir, ODBC-Probleme zu lösen.

+0

Ich habe gerade das Abfrage-Tool installiert. Ich musste die Datenquelle anders angeben (keine Verbindungszeichenfolge). Ich habe "SELECT COUNT (*) FROM table" ausgeführt. Es gab mir die gleiche Antwort wie mein Python-Code und eine andere (kleinere) Antwort auf dieselbe Anweisung in Access. Also, gute Nachrichten, es ist nicht mein Python-Code oder pyodbc. Schlechte Nachrichten: Ich kann Access/ODBC nicht vertrauen. – Oddthinking

+0

Access ist ein wirklich cooles Tool, aber es ist fehlerhaft. Zum Beispiel manchmal, wenn Sie eine Abfrage in SQL schreiben und später bearbeiten, wird es Ihnen sagen, Sie haben Syntaxfehler, die Sie korrigiert - Sie müssen die Abfrage in Notepad und zurück in eine neue Access sql Design-Ansicht kopieren. Es sieht nicht so aus, als ob Access besser wird, nur verwirrender und komplizierter. –

+0

Wird Access in dieser Frage verwendet? Soweit ich das beurteilen kann, wird nur Jet verwendet, also ist der Access-QBE nicht beteiligt. –

1

Sind die Felder indiziert? Ist dies der Fall, ist möglicherweise einer der Indizes beschädigt und Sie müssen die MDB-Datei komprimieren. Wenn ein Index beschädigt ist, kann dies zu schwerwiegenden Problemen führen. Sie könnten bestehende Beziehungen verlieren (wenn der korrupte Index der PK ist), oder Sie könnten Daten verlieren. Sie müssen also ein Backup haben, bevor Sie das tun.Wenn es einen beschädigten Index gibt, denke ich, dass die interaktive Access-Komprimierungsoperation Ihnen das sagen wird, aber wenn nicht, können Sie nach der MSysCompactErrors-Tabelle suchen, die Ihnen sagen wird, welche Fehler während des Komprimierens aufgetreten sind.

Dieses nur sehr selten vorkommt und eine von zwei Dinge zeigen kann:

  1. schlechtes Anwendungsdesign, einschließlich veralteter Jet-Versionen (Jet 4 vor dem Service Pack 6 bis diese sehr anfällig war, und das ist, wo ich gestoßen es).

  2. unzuverlässige Betriebsumgebung (Netzwerk/Hardware/Software).

Natürlich ist dieser Vorschlag ein echter Totalen, aber es ist auf jeden Fall eine Ursache für unterschiedliche Ergebnisse (die häufigste wäre auf dem beschädigten Index ORDER BY und Sie werden mit einem anderen Datensatz am Ende zählen als mit einer anderen ORDER BY).

+0

Ich werde das überprüfen. Mein erster Schritt war, meine JET-Version zu überprüfen. Ich verwende die neueste Version, die mit Vista Service Pack 1 geliefert wurde. (Http://support.microsoft.com/kb/239114 war meine Referenz.) – Oddthinking

1

Ich vermute, das Problem könnte sein, dass Sie die Abfrage nicht festgeschrieben haben. PYODBC startet mit autocommit = False und daher startet jede Abfrage wie select, insert, update usw. eine Transaktion, die Sie ausführen müssen, um Wirkung zu erzielen. Entweder rufen Sie connection.autocommit = True oder rufen Sie cursor.execute("commit") nach der Abfrage und dann fetchall.

+0

Sie müssen sogar SELECT-Anweisungen festschreiben? –

+0

Ich weiß nicht über Access-Datenbank, aber wenn Sie SQL Server verwenden, bedeutet havin autocommit = False bedeutet implizite Transaktionen. http://msdn.microsoft.com/en-us/library/ms188317.aspx besagt, dass sogar SELECT eine Transaktion startet. –