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

Posted

技术标签:

【中文标题】将数据从 python pandas 数据帧导出或写入 MS Access 表【英文标题】:Exporting or writing data from python pandas data frame to MS Access table 【发布时间】:2017-10-16 10:00:47 【问题描述】:

我正在尝试将数据从 python pandas 数据帧导出到现有的 MS Access 表,我想用已更新的数据替换 MS Access 表(在 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 的替代方法,那也会有所帮助,我只需要知道如何导出我的数据。

【问题讨论】:

如果您查看documentation,它指出仅支持 sqlite3。您可以逐行解析数据帧并使用 INSERT 语句。 您好 Erik,感谢您的回复,我不太确定如何使用 INSERT?请您提供更多指导。 【参考方案1】:

如cmets中所说,to_sql只支持sqlite3

逐行解析数据框并将每一行插入到表中的示例方法:

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

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

    您需要有一个 Access 表来接收数据 该表需要具有正确的字段和正确的数据类型才能接收数据

您可以使用预先存在的表,例如您从中获取数据的索引表,但我不建议这样做(有丢失数据的风险)。如果这样做,您需要先清理桌子。清除索引表:

with cnxn.cursor() as crsr:
    crsr.execute("DELETE * FROM Index_data;")

【讨论】:

嗨,Erik,谢谢你说得有道理。我已经使用了您的代码,并且效果很好。 :-)【参考方案2】:

考虑将 pandas 数据帧导出到 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()

【讨论】:

【参考方案3】:

只是为了跟进 Parfait 的回答。我喜欢 ms 访问中的内联查询的想法,而不是遍历数据帧中的行。但是,我遇到了看起来像数字的字段(对于 Excel 或 Access)的问题;那些带有前导零的字段。我的环境中有很多这样的人。对于那些,我只是使用 csv 模块将它们用引号括起来。 像这样的:

from pathlib import Path
import csv
csv_file = Path(Path.cwd(), ms_access_table_name + '.csv')
my_df.to_csv(csv_file, sep = ',', quoting=csv.QUOTE_NONNUMERIC , index=False)
ms_sql = f'INSERT INTO ms_access_table_name (ms_access_columns) \n' +\
            f'SELECT ms_access_columns \n' + \
            f'FROM [text;HDR=Yes;FMT=Delimited(,);IMEX=2;Database=Path.cwd()].ms_access_table_name + ".csv"'
cursor.execute(ms_sql)
cursor.commit()

cursor.close()
conn.close()

【讨论】:

以上是关于将数据从 python pandas 数据帧导出或写入 MS Access 表的主要内容,如果未能解决你的问题,请参考以下文章

Python pandas:使用整数将数据帧输出到csv

使用 SQLAlchemy 将 pandas 数据帧导出到 MySQL 时出现操作错误 2055

从 Python 的 pandas 中的数据帧制作 matplotlib 散点图

如何将SalesForce数据导入Python Panda数据帧

Elasticsearch:将数据从 Elasticsearch 和 Kibana 导出到 Pandas Dataframe

Elasticsearch:将数据从 Elasticsearch 和 Kibana 导出到 Pandas Dataframe