Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过Python使用ADO将数据插入MS Access数据库时出现问题_Python_Ms Access_Ado_Comtypes - Fatal编程技术网

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

通过Python使用ADO将数据插入MS Access数据库时出现问题,python,ms-access,ado,comtypes,Python,Ms Access,Ado,Comtypes,[编辑2:以下答案中的更多信息和调试…] 我正在编写一个python脚本,将MS Access数据库导出到一系列文本文件中,以实现更有意义的版本控制(我知道为什么要访问?为什么我不使用现有的解决方案?让我们说这些限制不是技术性的) 我已经通过comtypes库使用ADO和ADOX成功地导出了数据库的完整内容和结构,但是重新导入数据时遇到了问题 我将每个表的内容导出到一个文本文件中,每行都有一个列表,如下所示: [-9, u'No reply'] [1, u'My home is as clean

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

我正在编写一个python脚本,将MS 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,而不管数据类型如何。。。有什么想法吗?

是否将
数据[i]
视为字符串?如果在设置
rs.Fields[i].Value
时将其强制转换为int/double,会发生什么情况


另外,当设置后打印出
rs.Fields[i].Value的内容时会发生什么情况?

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

每个“Inserted…”行中的最后一个值是调用rs.Fields[i].value之后再调用rs.Update()的结果。“After…”行显示调用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]
正如您所看到的,在您提交结果之前,结果是可靠的,然后。。。没有。

并找到了答案

    rs = client.CreateObject("ADODB.Recordset")
需要:

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

现在我只需要调查一下原因。只希望这个问题能为其他人节省几个小时…

请参见编辑-奇怪的是,我需要专门将int/double转换为string以使其正常工作…解决方案的其余部分是将“rs.Fields[I].Value=data[I]”更改为“rs.Fields[I].Value=str(data[I])?不,否。应该明确地说:添加dynamic=True解决了原始问题和后续问题以及可变结果。一旦它就位,rs.Fields[i].Value=data[i]就工作得很好,事实上,将数字转换为字符串会引发类型不匹配错误。Kewl,我不清楚答案。在这一点上,我要说的是,把你自己的答案标记为接受。
    rs = client.CreateObject("ADODB.Recordset", dynamic=True)