使用 fast_executemany 写入 MS-Access DB 不起作用

Posted

技术标签:

【中文标题】使用 fast_executemany 写入 MS-Access DB 不起作用【英文标题】:Writing to MS-Access DB with fast_executemany does not work 【发布时间】:2020-06-25 10:24:21 【问题描述】:

我在将数据加载到访问数据库时遇到问题。出于测试目的,我构建了一个小转换函数,它从 hdf 文件中获取所有数据集并将其写入 accdb。如果没有 @event.listens_for(engine, "before_cursor_execute") 功能,它可以工作,但速度非常慢。有了它,它会产生一种奇怪的行为。它在数据库中只创建一个空表(从第一个 df 开始)并完成执行。 for 循环永远不会完成,也不会引发错误。

可能是因为 sqlalchemy-access 包不支持 fast_executemany 但找不到任何相关信息。你们有没有什么意见可以告诉我如何解决它或能够以更快的方式将数据写入数据库?

非常感谢!

import urllib
from pathlib import Path
from sqlalchemy import create_engine, event

# PATHS
HOME = Path(__file__).parent
DATA_DIR = HOME / 'output'

FILE_ACCESS = DATA_DIR / 'db.accdb'
FILE_HDF5 = DATA_DIR / 'Data.hdf'

# FUNCTIONS
def convert_from_hdf_to_accb():
    # https://github.com/gordthompson/sqlalchemy-access/wiki/Getting-Connected
    driver = 'Microsoft Access Driver (*.mdb, *.accdb)'
    conn_str = 'DRIVER=;DBQ=;'.format(driver, FILE_ACCESS)
    conn_url = "access+pyodbc:///?odbc_connect=".format(urllib.parse.quote_plus(conn_str))

    # https://medium.com/analytics-vidhya/speed-up-bulk-inserts-to-sql-db-using-pandas-and-python-61707ae41990
    # https://github.com/pandas-dev/pandas/issues/15276
    # https://***.com/questions/48006551/speeding-up-pandas-dataframe-to-sql-with-fast-executemany-of-pyodbc
    engine = create_engine(conn_url)

    @event.listens_for(engine, "before_cursor_execute")
    def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
        if executemany:
            cursor.fast_executemany = True

    with pd.HDFStore(path=FILE_HDF5, mode="r") as store:
        for key in store.keys():
            df = store.get(key)
            df.to_sql(name=key, con=engine, index=False, if_exists='replace')

            print(' IT NEVER REACHES AND DOESNT RAISE AN ERROR :( ')

# EXECUTE
if __name__ == "__main__":
    convert_from_hdf_to_accb()

【问题讨论】:

如果您的最终目标是将 HDF 文件有效地导入 Access,我会使用 HDF ODBC 连接器直接从 Access 本身执行此操作。不过,如果这只是一个测试,我真的没有答案。 【参考方案1】:

可能是因为 sqlalchemy-access 包不支持 fast_executemany

确实如此。 pyodbc 的fast_executemany 功能要求驱动程序支持称为“参数数组”的内部 ODBC 机制,而 Microsoft Access ODBC 驱动程序不支持它们。

另见

https://github.com/mkleehammer/pyodbc/wiki/Driver-support-for-fast_executemany

【讨论】:

以上是关于使用 fast_executemany 写入 MS-Access DB 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

我可以将 pyodbc executemany 与 sql 存储过程一起使用吗?

为啥我会在一个很小的 ​​df 上使用 fast_executemany 出现内存错误?

使用 pyODBC 的 fast_executemany 加速 pandas.DataFrame.to_sql

(fast_executemany = True) 错误“[ODBC Driver 17 for SQL Server]强制转换规范 (0) (SQLExecute)'的字符值无效”)

Linux上的pyodbc fast_executemany在插入时出现乱码

使用 Sqoop 将数据从 MS-SQL 服务器写入 HDFS