在Ubuntu 11.10上使用python和unixODBC读取MS Access JET 4数据库(.mdb):获取错误的值

时间:2011-11-11 09:15:04

标签: python pyodbc unixodbc mdbtools

我在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 /数据库处理也很陌生。我花了3天的时间试图解决这个问题,但最后两个都没有。

问题:我可以读取数据库,但这些值没有正确编码/格式化。

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]),但似乎被Column Size / StrLen Or Ind缩短为8,因为结果输出长度为8个字符'03 / 14/03',虽然我认为大小8是指字节(?)。

第2列是整数值1,但在缓冲区中它被读为49.我还没弄清楚为什么,但它读取所有整数值为ascii代码/数字字符(1变为49,2变为50等),其中相当不方便,当数量变大时我不知道如何处理这个问题(例如1728变为942815025)。缓冲区中也会读取双数字。

来自日志,第1列和第2列的SQLDescribeCol(与下面链接的完整日志文件中的相同):

[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提供的表格的列:

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

如果有人有任何关于如何解决此问题的提示(包括简单的数据库转换,因为如果我这样做,我必须经常转换),我们将不胜感激!如果需要更多信息,我可以提供!

谢谢!

0 个答案:

没有答案