【问题标题】:Problem Inserting data into MS Access database using ADO via Python问题通过 Python 使用 ADO 将数据插入 MS Access 数据库
【发布时间】:2010-10-12 21:24:52
【问题描述】:

[编辑 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...有什么想法吗?

【问题讨论】:

    标签: python ms-access ado comtypes


    【解决方案1】:

    找到了答案。

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

    需要:

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

    现在我只需要调查原因。只是希望这个问题可以为其他人节省几个小时......

    【讨论】:

    • 解决方案的其余部分是将“rs.Fields[i].Value = data[i]”更改为“rs.Fields[i].Value = str(data[i]) “?
    • 不,不。应该明确地说:添加 dynamic=True 既解决了数值的原始问题,也解决了结果可变的后续问题。一旦到位,rs.Fields[i].Value = data[i] 工作正常,实际上将数字转换为字符串会引发类型不匹配错误。
    • Kewl,我并不清楚答案。在这一点上,我会说将您自己的答案标记为已接受。
    【解决方案2】:

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

    另外,设置rs.Fields[i].Value的内容后打印出来会怎样?

    【讨论】:

    • 查看编辑 - 奇怪的是我需要专门从 int/double 转换为 string 才能让它工作......
    【解决方案3】:

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

    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]
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多