【发布时间】:2015-11-06 23:44:49
【问题描述】:
我有一些相当大的 pandas DataFrame,我想使用新的批量 SQL 映射通过 SQL Alchemy 将它们上传到 Microsoft SQL Server。 pandas.to_sql 方法虽然不错,但速度很慢。
我在编写代码时遇到问题...
我希望能够向这个函数传递一个我称之为table 的pandas DataFrame、一个我称之为schema 的模式名称以及一个我称之为name 的表名。理想情况下,该函数将 1.) 如果表已存在,则删除该表。 2.)创建一个新表 3.)创建一个映射器和 4.)使用映射器和熊猫数据进行批量插入。我被困在第 3 部分。
这是我的(诚然粗略)代码。我正在为如何让映射器功能与我的主键一起工作而苦苦挣扎。我真的不需要主键,但映射器功能需要它。
感谢您的见解。
from sqlalchemy import create_engine Table, Column, MetaData
from sqlalchemy.orm import mapper, create_session
from sqlalchemy.ext.declarative import declarative_base
from pandas.io.sql import SQLTable, SQLDatabase
def bulk_upload(table, schema, name):
e = create_engine('mssql+pyodbc://MYDB')
s = create_session(bind=e)
m = MetaData(bind=e,reflect=True,schema=schema)
Base = declarative_base(bind=e,metadata=m)
t = Table(name,m)
m.remove(t)
t.drop(checkfirst=True)
sqld = SQLDatabase(e, schema=schema,meta=m)
sqlt = SQLTable(name, sqld, table).table
sqlt.metadata = m
m.create_all(bind=e,tables=[sqlt])
class MyClass(Base):
return
mapper(MyClass, sqlt)
s.bulk_insert_mappings(MyClass, table.to_dict(orient='records'))
return
【问题讨论】:
-
看来您正在自己重新创建
to_sql函数,我怀疑这会更快。将数据写入 SQL 的瓶颈主要在于 python 驱动程序(在您的情况下为pyobdc),这是您在上述实现中无法避免的事情。此外,to_sql不使用 ORM,即使在使用批量插入时,它也被认为比 CORE sqlalchemy 慢(docs.sqlalchemy.org/en/latest/faq/…) -
此外,如果
to_sql太慢,并且您无法改进它(例如通过调整连接参数、使用的驱动程序(例如 pymssql)、互联网速度、通过删除表上的约束等),更快的替代方法是将数据写入 csv,然后将其加载到 SQL 表中。 -
@joris 谢谢。看来这里列出的“批量操作”有点用词不当。 docs.sqlalchemy.org/en/rel_1_0/orm/… 我真正需要做的是将熊猫数据文件输出到文本文件并像这样编写 BULK INSERT 操作... stackoverflow.com/questions/29638136/…
-
是的,但那是为了提高 sqlalchemy ORM 的速度,它比核心 sqlalchemy 有更多的功能。但是 pandas
to_sql根本不使用 ORM,正如我之前所说,实际上已经在进行批量插入。 -
@joris 好吧,我走这条路的原因是我可以在 SQL Server 上运行 'BULK INSERT dbo.MyTable FROM \\fileserver\folder\doc.txt' 并且性能是伟大的。我在想的是,当 BULK INSERT 语句使用“VALUES”而不是“FROM”时,这就是真正的性能损失所在。换句话说,从 sql server 到文件服务器的连接比从我的虚拟机到 SQL Server 的连接要好。谢谢。
标签: python pandas sqlalchemy