Проблема Вставка данных в базу данных MS Access с использованием ADO через Python

[Редактировать 2: Дополнительная информация и отладка в ответе ниже …]

Я пишу скрипт python для экспорта баз данных MS Access в ряд текстовых файлов, чтобы обеспечить более значимый контроль версий (я знаю – почему Access? Почему я не использую существующие решения? Давайте просто скажем, что ограничения не технический характер).

Я успешно экспортировал полное содержимое и структуру базы данных с помощью ADO и ADOX через библиотеку comtypes, но у меня проблема с повторным импортом данных.

Я экспортирую содержимое каждой таблицы в текстовый файл со списком в каждой строке, например:

[-9, u'No reply'] [1, u'My home is as clean and comfortable as I want'] [2, u'My home could be more clean or comfortable than it is'] [3, u'My home is not at all clean or comfortable'] 

И следующая функция для импорта указанного файла:

 import os import sys import datetime import comtypes.client as client from ADOconsts import * from access_consts import * class Db: def create_table_contents(self, verbosity = 0): conn = client.CreateObject("ADODB.Connection") rs = client.CreateObject("ADODB.Recordset") conn.ConnectionString = self.new_con_string conn.Open() for fname in os.listdir(self.file_path): if fname.startswith("Table_"): tname = fname[6:-4] if verbosity > 0: print "Filling table %s." % tname conn.Execute("DELETE * FROM [%s];" % tname) rs.Open("SELECT * FROM [%s];" % tname, conn, adOpenDynamic, adLockOptimistic) f = open(self.file_path + os.path.sep + fname, "r") data = f.readline() print repr(data) while data != '': data = eval(data.strip()) print data[0] print rs.Fields.Count rs.AddNew() for i in range(rs.Fields.Count): if verbosity > 1: print "Into field %s (type %s) insert value %s." % ( rs.Fields[i].Name, str(rs.Fields[i].Type), data[i]) rs.Fields[i].Value = data[i] data = f.readline() print repr(data) rs.Update() rs.Close() conn.Close() 

Все работает отлично, за исключением того, что числовые значения (double и int) вставляются как нули. Любые идеи о том, связана ли проблема с моим кодом, eval, comtypes или ADO?

Изменить: я исправил проблему с введением чисел – их отличать, поскольку строки (!), Похоже, решают проблему как для двух, так и для целочисленных полей.

Однако у меня теперь есть другая проблема, которая ранее была скрыта выше: первое поле в каждой строке устанавливается равным 0 независимо от типа данных … Любые идеи?

    И нашел ответ.

      rs = client.CreateObject("ADODB.Recordset") 

    Должно быть:

      rs = client.CreateObject("ADODB.Recordset", dynamic=True) 

    Теперь мне просто нужно выяснить, почему. Просто надеюсь, что этот вопрос спасет кого-то еще несколько часов …

    Являются ли data[i] обрабатываемыми как строка? Что произойдет, если вы специально используете его как int / double при установке rs.Fields[i].Value ?

    Кроме того, что происходит, когда вы распечатываете содержимое rs.Fields[i].Value после его установки?

    Не полный ответ, но, похоже, проблема во время обновления. Я добавил дополнительный код отладки в процессе вставки, который генерирует следующее (пример обновления одной строки):

     Inserted into field ID (type 3) insert value 1, field value now 1. Inserted into field TextField (type 202) insert value u'Blah', field value now Blah. Inserted into field Numbers (type 5) insert value 55.0, field value now 55.0. After update: [0, u'Blah', 55.0] 

    Последнее значение в каждой строке «Inserted …» является результатом вызова rs.Fields [i]. Перед вызовом rs.Update (). Строка «После …» показывает результаты вызова rs.Fields [i]. После вызова rs.Update ().

    Что еще более раздражает, так это то, что он не надежно проваливается. Повторное использование одного и того же кода в тех же записях через несколько минут сгенерировало:

     Inserted into field ID (type 3) insert value 1, field value now 1. Inserted into field TextField (type 202) insert value u'Blah', field value now Blah. Inserted into field Numbers (type 5) insert value 55.0, field value now 55.0. After update: [1, u'Blah', 2.0] 

    Как вы можете видеть, результаты надежны, пока вы их не зафиксируете, тогда … нет.