使用pyodbc从Python应用程序将值插入Access 2003数据库

时间:2014-08-06 19:29:47

标签: python database ms-access insert pyodbc

我过去经常检查stackoverflow,并且总能找到我一直在寻找的东西,但我似乎无法让这个工作,所以我问我的第一个问题。

我不是真正的程序员,但我在工作中提到了Python,现在我有了一个Python项目。我实际上已经把一切都搞清楚了,但是将值插入数据库会让我陷入困境。

基本问题:

我有一个使用Python和tkinter构建的表单。当按下窗体上的按钮时,我希望将值插入到数据库中。

详情:

我正在使用Python 3.4,pyodbc和Access 2003数据库。

数据库只是一个名为file_info的表,它有以下字段,字段数据类型列在管道后面。

ID |自动编号

filename |文本

日期|日期/时间

batch_amount |编号

parcel_amount |编号

sum_amount |编号

最终我想插入一些在其他函数中计算的值,但是目前我只是想通过函数插入一些设置值而我无法让它工作。

连接字符串:

db_file = r'''C:\Users\amarquart\Documents\testlockboxdb.mdb'''
user = 'admin'
password = ''
odbc_conn_str = 'DRIVER={Microsoft Access Driver (*.mdb,   
*.accdb)};DBQ=%s;UID=%s;PWD=%s' % \
(db_file, user, password)

conn = pyodbc.connect(odbc_conn_str)
cur = conn.cursor()     

程序编译并运行正常,所以我假设错误不是连接字符串。所以这里是我在我的函数中使用的代码的一些例子无济于事。

def insert_data():
    sql = '''INSERT INTO file_info
    (
      [ID],
      [date],
      [filename],
      [batches_amount],
      [parcels_amount],
      [sum_amount],
    )
    VALUES
    (
      '1',
      'test',
      '8/01/2014 1:00:00 PM',
      '1',
      '1',
      '1',
    );'''

    cur.execute(sql)

    conn.commit()
    cur.commit()
    conn.close()

这给出了这个错误:

Tkinter回调中的异常 Traceback(最近一次调用最后一次):   文件“C:\ Python34 \ lib \ tkinter__init __。py”,第1487行,调用     return self.func(* args)   文件“C:/ Users / amarquart / PycharmProjects / Grid testing / Source / Grid testing.py”,第170行,运行中     insert_data()   在insert_data中输入文件“C:/ Users / amarquart / PycharmProjects / Grid testing / Source / Grid testing.py”,第36行     cur.execute(SQL) pyodbc.ProgrammingError:('42000','[42000] [Microsoft] [ODBC Microsoft Access驱动程序] INSERT INTO语句中的语法错误。( - 3502)(SQLExecDirectW)')

def insert_data():
    sql = ("""INSERT INTO [file_info] ([ID], [date], [filename], [batches_amount],     
         [parcels_amount], [sum_amount])
          VALUES (?, ?, ?, ?, ?, ?)""", [1, '8/01/2014 1:00:00 PM', 'test', 10, 4, 2])
    cur.execute(sql)

    conn.commit()
    cur.commit()
    conn.close()

给出了这个错误:

Tkinter回调中的异常 Traceback(最近一次调用最后一次):   文件“C:\ Python34 \ lib \ tkinter__init __。py”,第1487行,调用     return self.func(* args)   文件“C:/ Users / amarquart / PycharmProjects / Grid testing / Source / Grid testing.py”,第154行,运行中     insert_data()   在insert_data中输入文件“C:/ Users / amarquart / PycharmProjects / Grid testing / Source / Grid testing.py”,第20行     cur.execute(SQL) TypeError:要执行的第一个参数必须是字符串或unicode查询。

def insert_data():
    sql = """
    INSERT INTO file_info (ID, date, filename, batches_amount, parcels_amount, sum_amount)
    VALUES (1, '8/01/2014 1:00:00 PM', 'test', 2, 2, 2)
    """ 
    cur.execute(sql)

    conn.commit()
    cur.commit()
    conn.close()    

与上一个代码

给出相同的错误
def insert_data():
   cur.execute("INSERT INTO file_info VALUES (AutoNumber, Text, Date/Time, Number,
               Number, Number)",
(1, 'test', '8/01/2014 1:00:00 PM', 2, 2, 2))
   conn.commit()
   cur.commit()
   conn.close()

发出此错误:

Tkinter回调中的异常 Traceback(最近一次调用最后一次):   文件“C:\ Python34 \ lib \ tkinter__init __。py”,第1487行,调用     return self.func(* args)   文件“C:/ Users / amarquart / PycharmProjects / Grid testing / Source / Grid testing.py”,第153行,运行中     insert_data()   在insert_data中输入文件“C:/ Users / amarquart / PycharmProjects / Grid testing / Source / Grid testing.py”,第19行     (1,'test','8/01/2014 1:00:00 PM',2,2,2)) pyodbc.ProgrammingError:('SQL包含0个参数标记,但提供了6个参数','HY000')

我猜我所尝试的一切都非常不正确,所以任何帮助都会非常感激。

谢谢大家。

编辑:

基于第一个响应的新尝试,唯一的区别是我使用三重引号,因为代码跨越2行

cur.execute("""INSERT INTO file_info (ID, date, filename, batches_amount,   
parcels_amount, sum_amount) 
         VALUES (1, 'test', '8/01/2014 1:00:00 PM', 2, 2, 2)""")
conn.commit()

发出此错误

Tkinter回调中的异常 Traceback(最近一次调用最后一次):   文件“C:\ Python34 \ lib \ tkinter__init __。py”,第1487行,调用     return self.func(* args)   在insert_data中输入文件“C:/ Users / amarquart / PycharmProjects / Grid testing / Source / Grid testing.py”,第19行     VALUES(1,'test','8/01/2014 1:00:00 PM',2,2,2)''') pyodbc.ProgrammingError:('42000','[42000] [Microsoft] [ODBC Microsoft Access驱动程序] INSERT INTO语句中的语法错误。( - 3502)(SQLExecDirectW)')

params = [(1, '8/01/2014 1:00:00 PM', 'test', 2, 2, 2)]
cur.executemany("""insert into file_info(ID, date, filename, batch_amount,   
parcel_amount, sum_amount)
                values (?, ?, ?, ?, ?, ?)""", params)
conn.commit()

发出此错误

Tkinter回调中的异常 Traceback(最近一次调用最后一次):   文件“C:\ Python34 \ lib \ tkinter__init __。py”,第1487行,调用     return self.func(* args)   在insert_data中输入文件“C:/ Users / amarquart / PycharmProjects / Grid testing / Source / Grid testing.py”,第20行     值(?,?,?,?,?,?)“”“,params) pyodbc.Error:('HYC00','[HYC00] [Microsoft] [ODBC Microsoft Access驱动程序]可选功能未实现(106)(SQLBindParameter)')

2 个答案:

答案 0 :(得分:5)

你几次尝试都很接近。 Date是Access中的reserved word,用括号括住列名,并确保列的顺序与值的顺序匹配:

...
sql = """
INSERT INTO file_info (ID, [date], filename, batches_amount, parcels_amount, sum_amount)
VALUES (1, '8/01/2014 1:00:00 PM', 'test', 2, 2, 2)
""" 
cur.execute(sql)
....

根据Gord的评论,Access支持参数化查询,因此理想的代码是:

....
params = (1, '8/01/2014 1:00:00 PM', 'test', 2, 2, 2)
sql = """
INSERT INTO file_info (ID, [date], filename, batches_amount, parcels_amount, sum_amount)
VALUES (?, ?, ?, ?, ?, ?)
""" 
cur.execute(sql, params)
...

答案 1 :(得分:3)

您的订单略有错误:值应位于列定义之后,并且在插入值之前,例如,在您的情况下:

cur.execute("INSERT INTO file_info (ID, filename, [date], batches_amount, parcels_amount, sum_amount) 
             VALUES (1, 'test', '8/01/2014 1:00:00 PM', 2, 2, 2)")
conn.commit()

这是标准的SQL插入语法,并不是pyodbc或Access特有的。请注意,您还可以使用占位符(?)作为值,然后提供值数组,请参阅docs,特别是executemany。

另请注意,您只需要调用conn.commit(),而不是cur.commit(),请参阅这些other docs中的插入

编辑:根据beargle的评论,您需要在[]中输入日期,因为它是您原始尝试中的保留字,但同样,您有日期和文件名价值倒退。一般情况下,尽量避免使用保留字作为字段名,这适用于除Access之外的其他数据库。