将数据从python pandas数据框导出或写入MS Access表

时间:2017-10-16 10:00:47

标签: python pandas ms-access

我正在尝试将数据从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,那也有帮助,我只需要知道如何导出我的数据。

3 个答案:

答案 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的F1F2列插入名为Output的表的Field1Field2字段中。

这有两个主要条件才能正常运作:

  1. 您需要有一个Access表来接收数据
  2. 该表需要具有正确的字段和正确的数据类型才能接收数据
  3. 您可以使用预先存在的表格,例如您从中获取数据的索引表格,但我不推荐它(丢失数据的风险)。如果这样做,则需要先清除表格。要清除索引表:

    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