【发布时间】:2016-02-22 08:44:50
【问题描述】:
我有 74 个相对较大的 Pandas DataFrame(大约 34,600 行和 8 列),我正试图尽快将它们插入 SQL Server 数据库。在做了一些研究之后,我了解到好的 olepandas.to_sql 函数不适用于 SQL Server 数据库中的如此大的插入,这是我最初采用的方法(非常慢 - 应用程序完成几乎一个小时 vs 大约一个小时)使用 mysql 数据库时需要 4 分钟。)
This article 和许多其他 StackOverflow 帖子有助于为我指明正确的方向,但我遇到了障碍:
出于上面链接中解释的原因,我正在尝试使用 SQLAlchemy 的核心而不是 ORM。所以,我将数据框转换为字典,使用pandas.to_dict,然后执行execute() 和insert():
self._session_factory.engine.execute(
TimeSeriesResultValues.__table__.insert(),
data)
# 'data' is a list of dictionaries.
问题是插入没有得到任何值——它们显示为一堆空括号,我得到这个错误:
(pyodbc.IntegretyError) ('23000', "[23000] [FreeTDS][SQL Server]Cannot
insert the value NULL into the column...
我传入的字典列表中有一些值,所以我不知道为什么这些值没有显示出来。
编辑:
下面是我要讲的例子:
def test_sqlalchemy_core(n=100000):
init_sqlalchemy()
t0 = time.time()
engine.execute(
Customer.__table__.insert(),
[{"name": 'NAME ' + str(i)} for i in range(n)]
)
print("SQLAlchemy Core: Total time for " + str(n) +
" records " + str(time.time() - t0) + " secs")
【问题讨论】:
-
使用 mysql 数据库大约需要 4 分钟 ...所以
to_sql()是一个可行的解决方案,只是 MSSQL 中的连接比 MySQL 慢吗?您使用的是哪个 ODBC API?数据库服务器是本地的还是远程的?考虑一个临时表导入,然后迁移到最终表。 -
@Parfait:使用
to_sql()可以在 MySQL 中产生可接受的性能,但在 MSSQL 中不行。我正在使用pyodbc。数据库是远程的,因此写入 CSV 文件然后通过原始 sql 代码进行批量插入在这种情况下也不会真正起作用。此外,用户需要批量管理权限才能执行此操作,而对于此应用程序的用户而言,这可能并不总是可行的。 -
考虑绕过 odbc 驱动程序并使用严格的 Python API - pmyssl 和 MySQL ODBC API? pymysql?两者的表结构和数据类型相同吗?相同数量的记录?真的调查这个。两者都是高级企业 RDMS,不应该执行那么宽的范围(4 分钟对 ~60 分钟)。
标签: python sql-server pandas sqlalchemy