Ubuntu 11.10 32 ビットで Python 2.7.2 (unixODBC 2.2.14、pyodbc 2.1.11、および mdbtools ドライバー) を使用して Microsoft Access データベース (JET 4 .mdb) を読み込もうとすると、問題が発生します。はい、私はそれが恐ろしい考えであることを知っていますが、奇妙なことに、それは私が見つけることができる最も簡単な解決策です. さまざまな理由で .mdb データベースを別の形式 (sqlite など) に変換することは避けたいのですが、これが理解できない場合は、これが唯一の解決策のようです。この質問が長くなってしまったことをお詫び申し上げます。また、Linux および odbc/database の取り扱いについても初心者です。私はこれを理解しようと 3 日間費やしましたが、最後の 2 日間はどこにも行きませんでした。
問題: データベースを読み取ることはできますが、値が正しくエンコード/フォーマットされていません。
Python コード:
import pyodbc
connection=pyodbc.connect('DSN=dbcon_test') # Driver = /usr/lib/libmdbodbc.so.0
cursor=connection.cursor()
cursor.execute('SELECT * FROM FIELDNOTES')
rows=cursor.fetchone()
出力:
行:
('03/14/03', 49, 49, None, 'visit\x00\xfd', None, 'upstream of ', 942815025)
次のようにする必要があります。
('03/14/03 15:40:00, 1, 1, None, 'visit', None, 'upstream of road, just below small drop, 1728)
私が考え、理解しようとしているのは、列情報の読み取り時 (SQLDescribeCol.c) および/またはデータのフェッチ時 (SQLFetch.c および SQLGetData.c) にエラーがあるということです。
たとえば、列 1 と 2 を見てみましょう。列 1 はタイム スタンプであり、そのように正しく識別されます (SQL_TYPE_TIMESTAMP)。また、正しい値をバッファに読み込みます (Buffer = [03/14/03 15:40:00]) が、結果の出力が 8 文字の長さ '03 であるため、8 である Column Size/StrLen Or Ind によってショートされているようです/14/03」、サイズ 8 はバイト (?) を指すと思っていましたが。
列 2 は整数値 1 ですが、バッファでは 49 として読み取られます。理由はわかりませんが、すべての整数値を ASCII コード/数字 (1 は 49、2 は 50 など) として読み取るため、かなり不便です。また、数値が大きくなった場合 (たとえば、1728 が 942815025 になる) に対処する方法がわかりません。double の数値もバッファーで正しく読み取られません。
ログの SQLDescribeCol、列 1 および 2 (以下にリンクされている完全なログ ファイルと同じ):
[ODBC][16118][1320928843.731400][SQLDescribeCol.c][243]
Entry:
Statement = 0xa0e1ab0
Column Number = 1
Column Name = 0xbffd2820
Buffer Length = 300
Name Length = (nil)
Data Type = 0xbffd281a
Column Size = 0xbffd2814
Decimal Digits = 0xbffd281c
Nullable = 0xbffd281e
[ODBC][16118][1320928843.731411][SQLDescribeCol.c][493]
Exit:[SQL_SUCCESS]
Column Name = [Date/Time]
Data Type = 0xbffd281a -> -1
Column Size = 0xbffd2814 -> 8
Decimal Digits = 0xbffd281c -> 0
Nullable = 0xbffd281e -> 0
[ODBC][16118][1320928843.731423][SQLDescribeCol.c][243]
Entry:
Statement = 0xa0e1ab0
Column Number = 2
Column Name = 0xbffd2820
Buffer Length = 300
Name Length = (nil)
Data Type = 0xbffd281a
Column Size = 0xbffd2814
Decimal Digits = 0xbffd281c
Nullable = 0xbffd281e
[ODBC][16118][1320928843.731434][SQLDescribeCol.c][493]
Exit:[SQL_SUCCESS]
Column Name = [Site]
Data Type = 0xbffd281a -> 4
Column Size = 0xbffd2814 -> 4
Decimal Digits = 0xbffd281c -> 0
Nullable = 0xbffd281e -> 0
ログ列 1 および 2 からの SQLGetData:
[ODBC][16118][1320928843.732565][SQLGetData.c][233]
Entry:
Statement = 0xa0e1ab0
Column Number = 1
Target Type = 1 SQL_CHAR
Buffer Length = 1024
Target Value = 0xbffd24dc
StrLen Or Ind = 0xbffd24d8
[ODBC][16118][1320928843.732584][SQLGetData.c][497]
Exit:[SQL_SUCCESS]
Buffer = [03/14/03 15:40:00]
Strlen Or Ind = 0xbffd24d8 -> 8
[ODBC][16118][1320928843.732595][SQLGetData.c][233]
Entry:
Statement = 0xa0e1ab0
Column Number = 2
Target Type = 4 SQL_INTEGER
Buffer Length = 4
Target Value = 0xbffd2950
StrLen Or Ind = 0xbffd295c
[ODBC][16118][1320928843.732606][SQLGetData.c][497]
Exit:[SQL_SUCCESS]
Buffer = [49]
Strlen Or Ind = 0xbffd295c -> 4
これらは、mdbtools によって提供されるテーブル abd の列です。
mdb-schema database.mdb -T FIELDNOTES
( [Size from MDB Viewer]
Date/Time DateTime (Short), 8
Site Long Integer, 4
Note_ID Long Integer, 4
Sampler Text (100), 100
Action Text (100), 100
Instrument ID Long Integer, 4
Memo Memo/Hyperlink (255), 0
Note_AutoID Long Integer 4
);
完全な ODBC ログ ファイル: http://pastebin.com/Q01ahwCW
これを解決する方法について誰かがヒントを持っている場合 (簡単なデータベース変換を含む) は、非常に頻繁に変換する必要があるため、非常に高く評価されます! さらに情報が必要な場合は、提供できます。
ありがとう!