问题使用ADO通过Python将数据插入MS Access数据库

时间:2009-03-12 10:52:29

标签: python ms-access ado comtypes

[编辑2:以下答案中的更多信息和调试...]

我正在编写一个python脚本,将MS Access数据库导出为一系列文本文件,以便进行更有意义的版本控制(我知道 - 为什么Access?为什么我不使用现有的解决方案?让我们说限制是不属于技术性质。)

我已经通过comtypes库使用ADO和ADOX成功导出了数据库的完整内容和结构,但是我在重新导入数据时遇到了问题。

我将每个表的内容导出到一个文本文件中,每行都有一个列表,如下所示:

[-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,无论数据类型如何......有什么想法吗?

3 个答案:

答案 0 :(得分:4)

找到了答案。

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

需要:

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

现在我只需要研究一下原因。只希望这个问题能在几个小时内拯救别人......

答案 1 :(得分:0)

data[i]被视为字符串吗?如果您在设置rs.Fields[i].Value时专门将其强制转换为int / double会发生什么?

此外,在设置rs.Fields[i].Value之后打印出{{1}}的内容会发生什么?

答案 2 :(得分:0)

尚未完整答案,但在更新过程中似乎存在问题。我在插入过程中添加了一些进一步的调试代码,生成以下内容(更新单行的示例):

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.Update()之前调用rs.Fields [i] .Value的结果。 “After ...”行显示调用rs.Update()后调用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: [1, u'Blah', 2.0]

正如您所看到的,在您提交结果之前,结果是可靠的,然后......不是。