2009-05-06 7 views
3

pyodbcをMicrosoft Jet経由で使用して、PythonプログラムからMicrosoft Access 2003データベースのデータにアクセスしています。PyODBCとMicrosoft Access:単純なクエリの結果が一貫しない

Microsoft Accessデータベースはサードパーティのものです。私はそのデータを読んでいるだけです。

私は一般的に必要なデータを抽出するのに成功していますが、最近はいくつかの相違があることに気付きました。

私は、フォームの単純なクエリ、それを煮詰めている:私は、フィールド名と値を難読化されてきましたが、本当に、それははるかに些細なものより取得していません

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

! Accessでクエリを実行すると、1つのレコードが返されます。

そこで私は、このようなコードで、pyodbc上でそれを実行します。

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

(繰り返しますが、それははるかに些細なものより取得していません!)

のqueryStringの値がカットされますAccessで作業クエリから貼り付けられましたが、は、レコードを返します。私は同じレコードを返すことを期待していました。

フィールド2の別の値を検索するようにクエリを変更すると、ビンゴが動作します。それはそれが拒否するいくつかの値だけです。

だから、私を助けてください。この不一致を説明するために、次にどこを調べるべきですか?私が些細な質問の結果を信頼できない場合、私はこのプロジェクトにチャンスがありません!

更新:さらに簡単になります。次のクエリは、それが時折データを移入するために他のアプリケーションでのキャッシングおよび/または不適切なトランザクション管理のいくつかのフォームに関連している場合、私は熟考

...テーブルFROM

SELECT COUNT(*)を異なる番号を与えます。

+0

クエリ文字列を実行するカーソルオブジェクトがありますか? Fetchallはカーソル上で呼び出され、行を生成します。 http://code.google.com/p/pyodbc/wiki/Rows – barrowc

+0

@barrowc、Interestingを参照してください。私はcursor()呼び出しがないことに気付かなかった。私はこれをどこかの例からコピーしたと確信しています。私はそれを[rows = connection.cursor()。execute(queryString).fetchall()]に追加しようとしましたが、Python DB API仕様よりもpyodbcが寛容です。 – Oddthinking

答えて

1

問題は、Access 2007へのアップグレードと、ソースから新しいデータベースのコピーをダウンロードするまでの間に解決されました。根本的な原因が何であったのかまだ分かりませんが、何らかの形でインデックスが破損していると思われます。

1

この問題を示す難読化されたデータベースを教えてください。私はこれを経験したことがありません。少なくともテーブル定義を与える - 列のいずれかが浮動小数点か小数点ですか?

+0

私はフロートのチェックの提案のためにあなたに投票しました。しかし、これは問題ではありません。更新されたバージョンではWHERE句がないことがわかります。 私はあなたのためにAccessからテーブルの説明を取得する方法に取り組んでいます。 – Oddthinking

1

これは馬鹿に聞こえるかもしれません。しかし...

&接続文字列(DSN)が同じファイルの場所を指していますか?

+0

これは完全に合理的な提案です。私はそれがそれほど些細なものであることが判明したことを本当に願っています! 私は二重チェックして、両方が同じディレクトリを指しています。 私はAccess 2003が混乱していて、削除された最近のMDBファイルを明らかに開いているのを見たので、ここでキャッシュや類似したことがあるのか​​疑問です。 – Oddthinking

+0

マシン上のPythonベースのアプリケーションを使用して、MDBファイルをネットワークパス上に使用しようとしていますか? – shahkalpesh

1

他のODBCツールで同じ問題がありますか。たとえば、Query Tool? ODBC接続マネージャでODBCトレースを有効にすることもできます。私は にアクセスすることはできませんし、そのsqlコマンドがトレースされるかどうかはわかりませんが、ODBCの問題を解決するのに役立つことがあります。

+0

質問ツールをインストールしました。データソースを別の方法で指定する必要がありました(接続文字列ではありません)。私は "SELECT COUNT(*)FROM table"を実行しました。それは私のPythonコードと同じ答えと、Accessの同じステートメントに対する別の(より小さい)答えを与えました。ですから、良いニュースは、私のPythonコードやpyodbcではありません。悪いニュース:Access/ODBCを信頼できません。 – Oddthinking

+0

アクセスは本当に素晴らしいツールですが、バグです。たとえば、SQLでクエリを作成して後で編集すると、修正された構文エラーがあることがわかります。クエリをメモ帳にコピーして、新しいAccess SQLデザインビューに戻す必要があります。私にとってアクセスが良くなっているようには思えず、ちょっと混乱して複雑になりました。 –

+0

この質問にアクセスしていますか?私の知る限りでは、Jetだけが使用されているため、Access QBEは関与していません。 –

1

フィールドにはインデックスが付けられていますか?その場合は、インデックスの1つが壊れている可能性があり、MDBファイルを圧縮する必要があります。 のインデックスがの場合、重大な問題が発生する可能性があります。既存の関係が失われる可能性があります(破損したインデックスがPKの場合)、データが失われる可能性があります。したがって、これを行う前にバックアップを取る必要があります。インデックスが壊れていると、私はInteractive Accessのコンパクトオペレーションがあなたに伝えると思いますが、そうでない場合は、コンパクト中にエラーが発生したことを示すMSysCompactErrorsテーブルを探すことができます。

これは非常にまれにのみ起こりません、次の2つのいずれかを示すことができます:廃止されたジェットのバージョンを含む

  1. 不正なアプリケーションの設計は、(サービスパック6の前にジェット4は、本に非常に敏感だった、と私は遭遇したところ、それはですそれ)。

  2. 信頼性のない動作環境(ネットワーク/ハードウェア/ソフトウェア)。もちろん

、この提案は本当のロングショットですが、それは(最も一般的には腐敗したインデックスにBY注文するだろうとあなたが別のレコードになってしまいます間違いなく、異なる結果の原因の一つであります他のORDER BYよりもカウントする)。

+0

これを確認します。私の第一歩はJETのバージョンをチェックすることでした。私はVista Service Pack 1に付属している最新のバージョンを実行しています。(http://support.microsoft.com/kb/239114は私の参照です) – Oddthinking

1

私は、クエリをコミットしなかった可能性があります。 PYODBCはautocommit = Falseで始まります。したがって、select、insert、updateなどのすべてのクエリは、コミットする必要があるトランザクションを開始します。 connection.autocommit = Trueに電話するか、クエリの後にcursor.execute("commit")と呼び出してからfetchallしてください。

+0

SELECTステートメントをコミットする必要がありますか? –

+0

私はAccessデータベースについてはわかりませんが、SQL Serverを使用している場合、havin autocommit = Falseは暗黙のトランザクションを持つことを意味します。 http://msdn.microsoft.com/en-us/library/ms188317.aspxでは、SELECTでさえトランザクションを開始すると記載されています。 –

関連する問題