我过去经常检查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)')
答案 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之外的其他数据库。