【问题标题】:Inserting values into a Access 2003 database from a Python application using pyodbc使用 pyodbc 从 Python 应用程序将值插入 Access 2003 数据库
【发布时间】:2014-08-06 19:29:47
【问题描述】:

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

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

基本问题:

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

细节:

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

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

ID |自动编号

文件名 |文字

日期 |日期/时间

batch_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 回调异常 回溯(最近一次通话最后): 调用中的文件“C:\Python34\lib\tkinter__init__.py”,第 1487 行 返回 self.func(*args) 运行中的文件“C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py”,第 170 行 插入数据() 文件“C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py”,第 36 行,在 insert_data cur.execute(sql) pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] 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 回调异常 回溯(最近一次通话最后): 调用中的文件“C:\Python34\lib\tkinter__init__.py”,第 1487 行 返回 self.func(*args) 运行中的文件“C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py”,第 154 行 插入数据() 文件“C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py”,第 20 行,在 insert_data 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 回调异常 回溯(最近一次通话最后): 调用中的文件“C:\Python34\lib\tkinter__init__.py”,第 1487 行 返回 self.func(*args) 运行中的文件“C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py”,第 153 行 插入数据() 文件“C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py”,第 19 行,在 insert_data (1, '测试', '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 回调异常 回溯(最近一次通话最后): 调用中的文件“C:\Python34\lib\tkinter__init__.py”,第 1487 行 返回 self.func(*args) 文件“C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py”,第 19 行,在 insert_data 值(1,'测试','8/01/2014 1:00:00 PM',2,2,2)''') pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] 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 回调异常 回溯(最近一次通话最后): 调用中的文件“C:\Python34\lib\tkinter__init__.py”,第 1487 行 返回 self.func(*args) 文件“C:/Users/amarquart/PycharmProjects/Grid testing/Source/Grid testing.py”,第 20 行,在 insert_data 值 (?, ?, ?, ?, ?, ?)""", 参数) pyodbc.Error: ('HYC00', '[HYC00] [Microsoft][ODBC Microsoft Access Driver]可选功能未实现 (106) (SQLBindParameter)')

【问题讨论】:

    标签: python database ms-access insert pyodbc


    【解决方案1】:

    你在几次尝试中都接近了。 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 的 cmets,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)
    ...
    

    【讨论】:

    • 这似乎是合理的——OP 的早期尝试之一确实将每个字段都包含在 [] 中。我也缺乏访问权限,也建议使用参数。抱歉,我误按了编辑而不是评论。
    • 叮叮!我们有赢家!我得到了要插入的数据。非常感谢。它只需要像括号这样的小东西。现在开始看看我是否可以从要插入的函数中获取数据。再次感谢!
    • 如果您将字段名称按正确的顺序排列,您的第一次尝试就会成功:-)
    • 总是发生,这些错误消息有点无用。对于一个说他不是程序员的人来说,你做得很好,但在未来,试着缩小你的问题范围——那里有相当多的时间。
    • 作为记录,是的,Access ODBC 确实支持来自 pyodbc/pypyodbc 的参数化查询。
    【解决方案2】:

    您的顺序略有错误:值应该在列定义之后,并且在插入值之前,例如,在您的情况下:

    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 的 cmets,您确实需要将日期放在 [] 中,因为它是一个保留字,您在最初的尝试中就有,但同样,您有日期和文件名价值观倒退。一般尽量避免使用保留字作为字段名,这适用于 Access 以外的其他数据库。

    【讨论】:

    • 感谢您的快速回复,我尝试了代码并将结果编辑到我的原始帖子中
    • 您的日期和文件名弄错了。这可能不是错误的意思,但这无济于事。另外,您是否尝试过在没有 tkinter 的情况下直接在 python 控制台中运行它,只是为了缩小范围。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多