2 回答
TA貢獻1859條經驗 獲得超6個贊
由于您不需要存儲過程的返回值,因此您應該能夠使用 pandas 的to_sql方法將行直接插入表中。這段代碼...
from time import time
import pandas as pd
import sqlalchemy as sa
from_engine = sa.create_engine("mssql+pyodbc://@mssqlLocal64")
to_engine = sa.create_engine(
"mssql+pyodbc://sa:[email protected]/mydb"
"?driver=ODBC+Driver+17+for+SQL+Server",
fast_executemany=False,
)
# set up test
to_cnxn = to_engine.raw_connection()
to_cnxn.execute("TRUNCATE TABLE MillionRows")
to_cnxn.commit()
num_rows_to_upload = 10000
df = pd.read_sql_query(
f"SELECT TOP {num_rows_to_upload} "
"[TextField], [LongIntegerField], [DoubleField], [varchar_column] "
"FROM MillionRows ORDER BY ID",
from_engine,
)
# run test
t0 = time()
df.to_sql("MillionRows", to_engine, index=False, if_exists="append")
s = f"{(time() - t0):0.1f} seconds"
print(f"uploading {num_rows_to_upload:,d} rows took {s}")
… 表示與您現在所做的工作大致相同的內部工作水平,即,將每個單獨的行作為單獨的調用上傳.execute。結果是
uploading 10,000 rows took 60.2 seconds
但是,簡單地更改to_engine為使用fast_executemany=True結果
uploading 10,000 rows took 1.4 seconds
TA貢獻1801條經驗 獲得超16個贊
關閉自動提交
?conn = pyodbc.connect(
? ? ? ? r'DRIVER={ODBC Driver 17 for SQL Server};SERVER=' + server_name + '; \
? ? ? ? Database=' + db_name + ';Trusted_Connection=yes;', timeout=5, autocommit=False)
?
并在此處和循環結束時提交。
? ? if index % 1000 == 0:
? ? ? ? ? ? print("Imported %s rows" % (index))
使用自動提交,您必須等待日志文件在每一行之后保存到磁盤。
為了進一步優化,如果您使用 SQL 2016+,請使用 JSON 將批量行發送到 SQL Server,并使用OPENJSON在服務器端進行解析。
添加回答
舉報
