2009-03-12 43 views
6

[Chỉnh sửa 2: Thêm thông tin và gỡ lỗi trong câu trả lời bên dưới ...]Sự cố Chèn dữ liệu vào cơ sở dữ liệu MS Access bằng ADO qua Python

Tôi đang viết một tập lệnh python để xuất cơ sở dữ liệu MS Access vào chuỗi văn bản các tệp để cho phép kiểm soát phiên bản có ý nghĩa hơn (tôi biết - tại sao Access? Tại sao tôi không sử dụng các giải pháp hiện có? Hãy chỉ nói các hạn chế không phải là bản chất kỹ thuật).

Tôi đã xuất thành công toàn bộ nội dung và cấu trúc của cơ sở dữ liệu bằng ADO và ADOX qua thư viện comtypes, nhưng tôi đang gặp sự cố khi nhập lại dữ liệu.

Tôi đang xuất khẩu các nội dung của mỗi bảng vào một tập tin văn bản với một danh sách trên mỗi dòng, như vậy:

[-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'] 

Và các chức năng sau đây để nhập khẩu các tập tin nói:

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() 

Mọi thứ hoạt động tốt ngoại trừ các giá trị số (double và int) đang được chèn dưới dạng số không. Bất kỳ ý tưởng về việc liệu vấn đề là với mã của tôi, eval, comtypes, hoặc ADO?

Chỉnh sửa: Tôi đã khắc phục sự cố khi chèn số - truyền chúng dưới dạng chuỗi (!) Dường như giải quyết vấn đề cho cả trường đôi và số nguyên.

Tuy nhiên, bây giờ tôi có vấn đề khác đã bị che khuất trước đó: trường đầu tiên trong mỗi hàng được đặt thành 0 bất kể loại dữ liệu ... Bất kỳ ý tưởng nào?

Trả lời

4

Và tìm thấy câu trả lời.

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

Nhu cầu là:

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

Bây giờ tôi chỉ cần nhìn vào lý do tại sao. Chỉ cần hy vọng câu hỏi này sẽ tiết kiệm cho người khác một vài giờ ...

+0

Và phần còn lại của giải pháp là thay đổi "rs.Fields [i] .Value = data [i]" thành "rs.Fields [i] .Value = str (data [i])"? – BIBD

+0

Không, không. Nên đã nói một cách rõ ràng: thêm dynamic = True đã giải quyết cả vấn đề ban đầu với các giá trị số, và vấn đề tiếp theo với các kết quả biến đổi. Khi nó đã được đặt đúng chỗ, rs.Fields [i] .Value = data [i] đã hoạt động tốt và trên thực tế, hãy truyền các con số dưới dạng chuỗi đã ném một lỗi không khớp loại. – mavnn

+0

Kewl, tôi không rõ câu trả lời. Tại thời điểm này tôi muốn nói đánh dấu câu trả lời của riêng bạn là Được chấp nhận. – BIBD

0

Có phải data[i] đang được coi là chuỗi không? Điều gì sẽ xảy ra nếu bạn chỉ định nó là int/double khi bạn đặt rs.Fields[i].Value?

Ngoài ra, điều gì sẽ xảy ra khi bạn in nội dung của rs.Fields[i].Value sau khi được đặt?

+0

Xem chỉnh sửa - bizarrely tôi cần thiết để đúc cụ thể từ int/đúp để chuỗi để làm cho nó hoạt động ... – mavnn

0

Chưa hoàn thành câu trả lời nhưng có vẻ như đã xảy ra sự cố trong quá trình cập nhật. Tôi đã thêm một số mã gỡ lỗi hơn nữa trong quá trình chèn mà tạo ra như sau (ví dụ về một hàng duy nhất được cập nhật):

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] 

Giá trị cuối cùng trong mỗi "chèn ..." dòng là kết quả của cuộc gọi rs.Fields [i] .Giá trị trước khi gọi rs.Update(). Dòng "After ..." hiển thị kết quả gọi rs.Fields [i] .Value sau khi gọi rs.Update().

Điều thậm chí còn khó chịu hơn là không đáng tin cậy. Chạy lại mã chính xác như nhau trên cùng ghi lại một vài phút sau đó tạo:

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] 

Như bạn có thể thấy, kết quả là đáng tin cậy cho đến khi bạn cam kết họ, sau đó ... không.

Các vấn đề liên quan