我正在尝试将数据从python pandas数据框导出到现有的MS Access表,我想用已更新的数据替换MS访问表(在python中) 我曾尝试使用pandas.to_sql,但收到错误消息。我发现这很奇怪,使用pandas.read_sql无缝地工作?
这是我的代码:
import pyodbc
import pandas as pd
conn_str = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=H:\Work\IndexTrader\Data\database\IndexData.accdb;'
)
cnxn = pyodbc.connect(conn_str)
SQL = 'SELECT * FROM Index_data;
从MS Access读取数据很好,见下文
dfins = pd.read_sql(SQL, cnxn)
然而,当我尝试回写并替换MS中的表时,它不起作用吗?
dfins.to_sql('Index_data', cnxn, if_exists='replace')
cnxn.close()
我得到的错误是:
DatabaseError: Execution failed on sql 'SELECT name FROM sqlite_master WHERE type='table' AND name=?;': ('42S02', "[42S02] [Microsoft][ODBC Microsoft Access Driver] The Microsoft Access database engine cannot find the input table or query 'sqlite_master'. Make sure it exists and that its name is spelled correctly. (-1305) (SQLExecDirectW)")
如果有替代方法而不是pandas.to_sql,那也有帮助,我只需要知道如何导出我的数据。
答案 0 :(得分:2)
如评论中所述,to_sql
仅支持slite3
逐行解析数据框并将每行插入表中的示例方法:
import pyodbc
import pandas as pd
conn_str = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=C:\Users\Erik\Desktop\TestDb.accdb;'
)
cnxn = pyodbc.connect(conn_str)
SQL = 'SELECT * FROM Index_data;'
dfins = pd.read_sql(SQL, cnxn)
for index, row in dfins.iterrows():
with cnxn.cursor() as crsr:
crsr.execute("INSERT INTO Output(Field1, Field2) VALUES(?,?)", row["F1"], row["F2"] )
这会将DataFrame的F1
和F2
列插入名为Output的表的Field1
和Field2
字段中。
这有两个主要条件才能正常运作:
您可以使用预先存在的表格,例如您从中获取数据的索引表格,但我不推荐它(丢失数据的风险)。如果这样做,则需要先清除表格。要清除索引表:
with cnxn.cursor() as crsr:
crsr.execute("DELETE * FROM Index_data;")
答案 1 :(得分:2)
考虑将pandas dataframe导出为CSV文件,然后在MS Access SQL中运行内联查询,因为Jet / ACE SQL引擎允许直接查询CSV。请注意文件夹是文件名上带有句点限定符的数据库。相应地调整列。
import pyodbc
import pandas as pd
conn_str = r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=H:\Work\IndexTrader\Data\database\IndexData.accdb;'
cnxn = pyodbc.connect(conn_str)
...
dfins.to_csv(r'C:\Path\To\myCSVFile.csv', index=False)
cur = cnxn.cursor()
cur.execute("INSERT INTO Index_data (Col1, Col2, Col3)" + \
" SELECT Col1, Col2, Col3" + \
" FROM [text;HDR=Yes;FMT=Delimited(,);Database=C:\Path\To\Folder].myCSVFile.csv t")
cnxn.commit()
答案 2 :(得分:1)
只是为了跟进 Parfait 的回答。我喜欢 ms access 中的内联查询的想法,而不是遍历数据帧中的行。但是,我遇到了看起来像数字的字段(对于 Excel 或 Access)的问题;那些带有前导零的字段。我们的环境中有很多这样的人。对于那些,我只是使用 csv 模块用引号将它们包装起来。 像这样:
numWidgets - retentionSize