Прочитайте базу данных MS Access JET 4 (.mdb), используя python и unixODBC в Ubuntu 11.10: получение неверных значений - PullRequest
3 голосов
/ 11 ноября 2011

У меня возникают некоторые проблемы при попытке чтения базы данных Microsoft Access (JET 4 .mdb) с использованием Python 2.7.2 (unixODBC 2.2.14, pyodbc 2.1.11 и драйвера mdbtools) в 32-разрядной версии Ubuntu 11.10. Да, я знаю, что это ужасная идея, но, как ни странно, это самое простое решение, которое я мог найти. Я хочу избежать преобразования базы данных .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, но в буфере он читается как 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

SQLGetData из столбцов журнала 1 и 2:

[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

Если у кого-нибудь есть какие-либо советы, как решить эту проблему (включая простое преобразование базы данных, поскольку мне пришлось бы преобразовывать очень часто, если бы я это сделал), это было бы очень признательно! Если потребуется дополнительная информация, я могу это предоставить!

Спасибо!

...