3

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

これを解決する方法について誰かがヒントを持っている場合 (簡単なデータベース変換を含む) は、非常に頻繁に変換する必要があるため、非常に高く評価されます! さらに情報が必要な場合は、提供できます。

ありがとう!

4

0 に答える 0