【问题标题】:import text file to Access 2003 database using Python使用 Python 将文本文件导入 Access 2003 数据库
【发布时间】:2014-08-26 16:31:12
【问题描述】:

我正在尝试使用我正在开发的 Python 3.4 应用程序将管道分隔的文本文件导入到具有现有表的 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 行 return self.func(args) 运行中的文件“C:/Users/amarquart/PycharmProjects/Database Testing/Source/DBTesting.py”,第 267 行 插入数据() 文件“C:/Users/amarquart/PycharmProjects/Database Testing/Source/DBTesting.py”,第 25 行,在 insert_data .format(fobj=fobj)) KeyError: 'Microsoft 文本驱动程序 ('

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 [文本;HDR=是;FMT=分隔;数据库=C:\Users\amarquart\Documents\functionDB.mdb].;{fobj}')""" SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 93-94: truncated \UXXXXXXXX escape

其他相关信息

数据库文件路径: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 行 返回 self.func(*args) 运行中的文件“C:/Users/amarquart/PycharmProjects/Database Testing/Source/DBTesting.py”,第 269 行 插入数据() 文件“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()

这也有效,而且可能更好?

感谢大家的帮助!

【问题讨论】:

  • 我不明白您查询的FROM 行。例如:FROM [Text;HDR=Yes;FMT=Delimited;Database=C:\Users\amarquart\Documents\functionDB.mdb].;{fobj}'。看起来您正试图在 SQL 中嵌入连接字符串?还是我误会了?
  • 我正在尝试将文本文件 (fobj) 中的值添加到数据库中,但我几乎只是在使用我能够在网上找到的内容,因此 FROM 来自我在互联网上发现的随机类似的东西。不过有一些进展,也许我更接近了。我将编辑我的问题以显示我现在的位置。
  • 请注意,您修改后的方法使用动态 SQL,因此容易受到 SQL 注入问题的影响。例如,e = "O'Leary" 会导致您的程序失败。这就是我在回答中使用参数化查询的原因。
  • @GordThompson 我认为这不是问题,因为文本文件只包含数字和单数字母,但我总是愿意尝试让我的程序更好。如果我们可以让文件名是动态的,我认为你的方式对我有用,因为程序必须用于导入不同的文件。目前我正在将文件名输入到条目小部件并读取条目小部件以获取 fobj 变量中的文件名。所以我需要一些类似于 open (r"fobj", "r") as pipeFile: 但这似乎不起作用。
  • @GordThompson 等等,我想我明白了,检查我对原始问题的编辑

标签: python database ms-access import pyodbc


【解决方案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()

【讨论】:

  • 感谢您的回答,您给了我尝试 line.split("|") 的想法,它似乎正在工作!
【解决方案2】:

这就是为我做的事

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

谢谢大家!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    相关资源
    最近更新 更多