我正在尝试从头开始编写2003 mdb文件。我已经有一个带有表和列名的文件(我有112列)。在尝试中,我从pandas DataFrame中读取了行(在我的代码中命名为节),并将这些行附加到mdb文件中。但是,当使用pyodbc INSERT INTO语法时,它给了我这个错误:
ProgrammingError :(“ 42000”,“ [42000] [Microsoft] [Driver ODBC Microsoft Access]表达式语法错误“ Equatorial-TB-BG-CA_IRI-1.0_SNP-1.0_ACA-0_ESAL-1000”。(-3100) (SQLExecDirectW)“)
这是我的代码:
for k in range(len(sections)):
cols = tuple(list(sections.columns))
vals = tuple(list(sections.iloc[k]))
action = 'INSERT INTO SECTIONS {columns} VALUES {values}'.format(columns = str(cols).replace("'",""), values = str(vals).replace("'",""))
cursor.execute(action)
conn.commit()
有人知道我为什么会遇到这种问题吗?
答案 0 :(得分:1)
实际上,这不是特定于Access的错误,而是一般的SQL错误,其中您的字符串文字没有正确地用引号引起来。因此,Access引擎假定它们是命名字段,并被连字符所复杂化,在这些字符中,引擎假定您正在运行减法表达式。
为演示该问题,请参见下文填写您的未知值。请注意,在VALUES
中传递的字符串项未加引号:
sections_columns = ['database', 'tool']
cols = tuple(list(sections_columns))
sections_vals = ['ms-access', 'pandas']
vals = tuple(list(sections_vals))
action = 'INSERT INTO SECTIONS {columns} VALUES {values}'.\
format(columns = str(cols).replace("'",""), values = str(vals).replace("'",""))
print(action)
# INSERT INTO SECTIONS (database, tool) VALUES (ms-access, pandas)
现在,您可以保留在str(vals)
中替换的单引号:
action = 'INSERT INTO SECTIONS {columns} VALUES {values}'.\
format(columns = str(cols).replace("'",""), values = str(vals))
print(action)
# INSERT INTO SECTIONS (database, tool) VALUES ('ms-access', 'pandas')
但更好的是,考虑使用qmark占位符对查询进行参数化并将值作为参数(cursor.execute(query, params)
的第二个参数)传递。这样可以避免引号或取消引号的字符串或数字值:
# MOVED OUTSIDE LOOP AS UNCHANGING OBJECTS
cols = tuple(sections.columns) # REMOVED UNNEEDED list()
qmarks = tuple(['?' for i in cols]) # NEW OBJECT
action = 'INSERT INTO SECTIONS {columns} VALUES {qmarks}'.\
format(columns = str(cols).replace("'",""), qmarks = str(qmarks))
# INSERT INTO SECTIONS (col1, col2, col3, ...) VALUES (?, ?, ?...)
for k in range(len(sections)):
vals = list(sections.iloc[k]) # REMOVED tuple()
cursor.execute(action, vals) # EXECUTE PARAMETERIZED QUERY
conn.commit()
更好的是,避免使用准备好的语句与executemany
中的DataFrame.values.tolist()
进行循环:
# PREPARED STATEMENT
cols = tuple(sections.columns)
qmarks = tuple(['?' for i in cols])
action = 'INSERT INTO SECTIONS {columns} VALUES {qmarks}'.\
format(columns = str(cols).replace("'",""), qmarks = str(qmarks))
# EXECUTE PARAMETERIZED QUERY
cursor.executemany(action, sections.values.tolist())
conn.commit()