使用Python将文本文件导入Access 2003数据库

2 投票
2 回答
2658 浏览
提问于 2025-04-18 18:36

我正在尝试用一个Python 3.4的应用程序把一个用管道符分隔的文本文件导入到一个已经存在的Access数据库表中,但遇到了一些问题。

这个应用程序将用于导入不同的文本文件,所以我使用了一个输入框来填写文件名,并希望把文件中的内容加载到我的表里。我尝试过直接用Access加载这个文件,结果很好,所以格式应该没问题。下面是我尝试过的一些代码,但都没有成功。

def insert_data():
inputfile = filepath.get()
fobj = open(inputfile)

cur.execute("""SELECT * INTO text_file_data
            FROM [odbc;Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq='{fobj}';];)"""
            .format(fobj=fobj))
conn.commit()

结果是这样的:

在Tkinter回调中出现异常 追踪(最近的调用在最后): 文件 "C:\Python34\lib\tkinter__init__.py",第1487行,在 call return self.func(args) 文件 "C:/Users/amarquart/PycharmProjects/Database Testing/Source/DBTesting.py",第267行,在 run insert_data() 文件 "C:/Users/amarquart/PycharmProjects/Database Testing/Source/DBTesting.py",第25行,在 insert_data .format(fobj=fobj)) KeyError: 'Microsoft Text Driver ('

还有

def insert_data():
inputfile = filepath.get()
fobj = open(inputfile)

cur.execute("""SELECT * INTO text_file_data
                FROM [Text;HDR=Yes;FMT=Delimited;Database=C:\Users\amarquart\Documents\functionDB.mdb].;{fobj}')"""
                .format(fobj=fobj))
conn.commit()   

结果是这样的:

文件 "C:/Users/amarquart/PycharmProjects/Database Testing/Source/DBTesting.py",第24行 FROM [Text;HDR=Yes;FMT=Delimited;Database=C:\Users\amarquart\Documents\functionDB.mdb].;{fobj}')""" 语法错误: (unicode错误) 'unicodeescape' 编解码器无法解码位置93-94的字节: 截断的 \UXXXXXXXX 转义

其他相关信息

数据库文件路径: C:\Alex\functionDB.mdb

使用fobj变量的文件路径: C:\Users\amarquart\Documents\5.txt

表名: text_file_data

我使用pyodbc进行连接

任何帮助都非常感谢。

谢谢,

亚历克斯

编辑 我的文本文件没有表头,下面是一个示例

D|1|502|2013|073306586|479.18

最新尝试:

def insert_data():
inputfile = filepath.get()
fobj = open(inputfile)

cur.execute("""INSERT INTO text_file_data (Letter, [Number], Batch, [Year], Parcel, Amount)
         VALUES ([Text;FMT=Delimited(|);HDR=NO;DATABASE=C:\Alex\functionDB.mdb].
         ['{fobj}')]""").format(fobj=fobj)

conn.commit()

给我以下结果:

在Tkinter回调中出现异常 追踪(最近的调用在最后): 文件 "C:\Python34\lib\tkinter__init__.py",第1487行,在 call return self.func(*args) 文件 "C:/Users/amarquart/PycharmProjects/Database Testing/Source/DBTesting.py",第269行,在 run insert_data() 文件 "C:/Users/amarquart/PycharmProjects/Database Testing/Source/DBTesting.py",第26行,在 insert_data ['{fobj}')]""").format(fobj=fobj) pyodbc.Error: ('21S01', '[21S01] [Microsoft][ODBC Microsoft Access Driver] 查询值的数量和目标字段不相同。(-3520) (SQLExecDirectW)')

编辑 搞定了

这和我在网上找到的所有信息都不一样,但它有效。它把文本文件中的所有数据都导入到数据库里,虽然数据的顺序不一样,但这其实没关系。

def insert_data():
inputfile = filepath.get()
fobj = open(inputfile)
for line in fobj:
    column = line.split('|')
    a = str(column[0])
    b = int(column[1])
    c = int(column[2])
    d = str(column[3])
    e = str(column[4])
    f = Decimal(column[5])

    cur.execute('''INSERT INTO text_file_data ([Letter], [Number], [Batch], [Year], [Parcel], [Amount])
         VALUES ('{a}', '{b}', '{c}', '{d}', '{e}', '{f}')'''.format(a=a, b=b, c=c, d=d, e=e, f=f))

conn.commit()

编辑,搞定了又一次

def insert_data():
inputfile = filepath.get()

qry = """INSERT INTO text_file_data ([Letter], [Number], [Batch], [Year], [Parcel], [Amount])
VALUES (?,?,?,?,?,?)"""

with open(inputfile) as pipeFile:
    for line in pipeFile:
        cur.execute(qry, line.split("|"))
conn.commit()

这个也有效,可能更好一些?

感谢大家的帮助!

2 个回答

0

这就是让我明白的原因

def insert_data():
inputfile = filepath.get()

qry = """INSERT INTO text_file_data ([Letter], [Number], [Batch], [Year], [Parcel], 
[Amount])
VALUES (?,?,?,?,?,?)"""

with open(inputfile) as pipeFile:
for line in pipeFile:
    cur.execute(qry, line.split("|"))
conn.commit()

谢谢大家!

1

我在用Python 2.7和pypyodbc时,搞出了一个勉强能用的办法……

# -*- coding: utf-8 -*-
import os
import pypyodbc

workingFolder = "C:\\Users\\Gord\\Desktop\\"
pipeFileName = "stuff.txt"
commaFileName = "stuff.csv"

with open (workingFolder + pipeFileName, "r") as pipeFile:
    data = pipeFile.read()
with open (workingFolder + commaFileName, "w") as commaFile:
    commaFile.write(data.replace("|",","))

connStr = (
    r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};' +
    r'DBQ=C:\Users\Public\Database1.accdb'
    )
db = pypyodbc.connect(connStr)

qry = """INSERT INTO text_file_data ([Letter], [Number], [Batch], [Year], [Parcel], [Amount]) 
    SELECT F1, F2, F3, F4, F5, F6 
    FROM [Text;FMT=Delimited;HDR=NO;IMEX=2;CharacterSet=437;Database="""
qry += workingFolder + "].[" + commaFileName.replace(".","#") + "]"

crsr = db.cursor()
crsr.execute(qry)
db.commit()
db.close()

os.remove(workingFolder + commaFileName)

……但是它把[Parcel]字段前面的零给去掉了。这个方法看起来效果更好一点(不过速度我就不太确定了):

# -*- coding: utf-8 -*-
import pypyodbc

connStr = (
    r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};' +
    r'DBQ=C:\Users\Public\Database1.accdb'
    )
db = pypyodbc.connect(connStr)

qry = """INSERT INTO text_file_data ([Letter], [Number], [Batch], [Year], [Parcel], [Amount]) 
    VALUES (?,?,?,?,?,?)"""

crsr = db.cursor()
with open (r"C:\Users\Gord\Desktop\stuff.txt", "r") as pipeFile:
    for line in pipeFile:
        crsr.execute(qry, line.split("|"))
db.commit()
db.close()

撰写回答