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/数据库处理也很陌生。我花了 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 或 Ind 缩短为 8,因为结果输出为 8 个字符长 '03 /14/03',虽然我认为大小 8 指的是字节(?)。

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

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