- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想将 Pandas 数据框作为一个整体放入 MS SQL Server 数据库的表中。像我这样的普通用户不允许批量插入。我正在使用 pyodbc 连接到我的数据库。我正在使用 Pandas 0.13.1。我在某处读到,从 0.14 版本开始,您可以使用 to_sql 方法,因此它不适用于我的 pandas 数据框。因此我使用了迭代器。我的数据框有 2 列:Col1 和 Col2。
我的代码正在运行,看起来像:
from pyodbc import connect
import pandasas pd
df = pd.read_csv('PathToMyCSVfile', sep=';', header=0)
cnxn = connect(DRIVER = '{SQL Server}', SERVER = 'MyServer', DATABASE = 'MyDatabase')
cursor = cnxn.cursor()
for index, row in df.interrows():
cursor.execute("INSERT INTO MySchema.MyTable VALUES (?,?)", df['Col1'][index], def['Col2'][index]
cnxn.commit()
如上所述,上面的代码可以工作,但速度很慢......我可以做些什么来加快速度?
最佳答案
您面临的瓶颈是您的代码为 DataFrame 中的每一行发送一个 INSERT 语句。也就是说,对于示例数据文件
id;txt
1;alpha
2;bravo
3;charlie
4;delta
5;echo
6;foxtrot
7;golf
您需要七 (7) 次往返服务器才能发送相当于
INSERT INTO MySchema.MyTable VALUES (1,'alpha')
INSERT INTO MySchema.MyTable VALUES (2,'bravo')
INSERT INTO MySchema.MyTable VALUES (3,'charlie')
...
INSERT INTO MySchema.MyTable VALUES (7,'golf')
您可以使用 Table Value Constructor 显着加快速度在一次往返中做同样的事情:
INSERT INTO MySchema.MyTable VALUES (1,'alpha'),(2,'bravo'),(3,'charlie'), ... ,(7,'golf')
下面的代码就是这样做的。当我使用包含 5000 行的文件对其进行测试时,使用 rows_per_batch=1000
(最大值)运行它比使用 rows_per_batch=1
(相当于您的目前的方法)。
import numpy
import pandas as pd
import pyodbc
import time
class MyDfInsert:
def __init__(self, cnxn, sql_stub, data_frame, rows_per_batch=1000):
# NB: hard limit is 1000 for SQL Server table value constructor
self._rows_per_batch = 1000 if rows_per_batch > 1000 else rows_per_batch
self._cnxn = cnxn
self._sql_stub = sql_stub
self._num_columns = None
self._row_placeholders = None
self._num_rows_previous = None
self._all_placeholders = None
self._sql = None
row_count = 0
param_list = list()
for df_row in data_frame.itertuples():
param_list.append(tuple(df_row[1:])) # omit zero-based row index
row_count += 1
if row_count >= self._rows_per_batch:
self._send_insert(param_list) # send a full batch
row_count = 0
param_list = list()
self._send_insert(param_list) # send any remaining rows
def _send_insert(self, param_list):
if len(param_list) > 0:
if self._num_columns is None:
# print('[DEBUG] (building items that depend on the number of columns ...)')
# this only happens once
self._num_columns = len(param_list[0])
self._row_placeholders = ','.join(['?' for x in range(self._num_columns)])
# e.g. '?,?'
num_rows = len(param_list)
if num_rows != self._num_rows_previous:
# print('[DEBUG] (building items that depend on the number of rows ...)')
self._all_placeholders = '({})'.format('),('.join([self._row_placeholders for x in range(num_rows)]))
# e.g. '(?,?),(?,?),(?,?)'
self._sql = f'{self._sql_stub} VALUES {self._all_placeholders}'
self._num_rows_previous = num_rows
params = [int(element) if isinstance(element, numpy.int64) else element
for row_tup in param_list for element in row_tup]
# print('[DEBUG] sql: ' + repr(self._sql))
# print('[DEBUG] params: ' + repr(params))
crsr = self._cnxn.cursor()
crsr.execute(self._sql, params)
if __name__ == '__main__':
conn_str = (
'DRIVER=ODBC Driver 11 for SQL Server;'
'SERVER=192.168.1.134,49242;'
'Trusted_Connection=yes;'
)
cnxn = pyodbc.connect(conn_str, autocommit=True)
crsr = cnxn.cursor()
crsr.execute("CREATE TABLE #tmp (id INT PRIMARY KEY, txt NVARCHAR(50))")
df = pd.read_csv(r'C:\Users\Gord\Desktop\Query1.txt', sep=';', header=0)
t0 = time.time()
MyDfInsert(cnxn, "INSERT INTO #tmp (id, txt)", df, rows_per_batch=1000)
print()
print(f'Inserts completed in {time.time() - t0:.2f} seconds.')
cnxn.close()
关于python - 无需使用 BULK INSERT 或 pandas to_sql 即可加快从 CSV 文件插入 SQL Server 的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46684359/
我们在Salesforce中有批量的短信Api代码吗?我在Twilio文档中没有找到。请在相同的指南中找到。。我已经搜索了Twilio文档和谷歌它,但没有找到相同的预期结果。是否有任何相关的帖子、代码
我正在尝试使用 libusb1.0.9 实现用户空间 USB 驱动程序。我有 lpc2148 蓝板(ARM7)。这个板由 Bertrik Sikken 先生加载了开源 USB 堆栈/固件。现在我的用户
在python脚本中, 我正在尝试 elasticsearch.helpers.bulk 来存储多个记录。 我将从另一个软件中获取json格式的字符串,并将其附加到源代码部分中 我通过此answer获
我正在管道中使用附件处理器Attachment Processor。 一切正常,但是我想做多个帖子,然后尝试使用bulk API。 批量工作也很好,但是我找不到如何发送url参数“pipeline =
我正在尝试基于简单的文本文件创建批量文件夹。 os.makedir 有助于创建新文件夹,但我不确定如何将 newpath 变量与文件夹列表合并。以下是我正在尝试的。我知道代码有语法错误。因此需要一些帮
代码如下: -- Created on 2010/11/04 by WANGNAN declare -- Local variables here&nb
我想知道是否使用 BULK COLLECT INTO多个集合保证行中的相应列在嵌套表中具有相同的索引。 例子: CREATE TABLE tx AS SELECT CAST(level AS INT)
我对以下 PL/SQL BULK-COLLECT 进行了修补,它对大表 (>50.000.000) 的更新速度惊人地快。唯一的问题是,它不执行每个表剩余 < 5000 行的更新。 5000 是 FET
我正在使用 BULK INSERT导入 CSV 文件。 CSV 文件中的一列包含一些包含分数的值(例如 1m½f )。 我不需要对分数进行任何数学运算,因为这些值仅用于显示目的,所以我将列设置为 nv
以下是我尝试上载具有一百万条记录的文件时遇到的一些问题。帮助我解决问题。当我尝试在博客中找到解决方案时,所有人都建议修改一些逻辑。但是我直接使用redisgraph-bulk-loader实用程序。
我将不得不使用 SQL Server 的 BULK INSERT 命令重写一些相当旧的代码,因为架构已更改,我突然想到也许我应该考虑改用 TVP 切换到存储过程,但我想知道是什么它可能对性能产生影响。
我需要在 azure 函数中发送批量补丁请求。我已经阅读了他们关于名为“bulk( )”的函数的非常简约的文档,这就是我目前拥有的 const response = await container.i
我试图将文档批量插入索引中。我需要_id等于我要插入的特定字段。我正在使用ES v6.6 POST productv9/_bulk { "index" : { "_index" : "productv
假设我有1000个用户,每个用户有50个文档(每个文档嵌入具有名称和电子邮件的用户对象),我需要为一组用户更新名称和电子邮件。 我想使用Bulk Api,但似乎bulk API仅支持“_id”作为参数
我正在使用curl将apache日志作为文档添加到使用批量API的elasticsearch中。我发布以下内容: {"index": {"_type": "apache", "_id": "123",
我正在使用 Marklogic 8.0.6,我想知道我们是否可以批量删除。例如,我想删除 150 000 个文档,这些文档可以通过 URI 列表或通用属性(字段 COUNTRY=US 和 COLOR=
我正在使用Elasticsearch版本6.7.2,但出现错误429 { "error": { "root_cause": [ {
我是Elasticsearch的新手。 我需要使用NEST api使用批量选项插入文档。 我必须从表中索引5000个文档。以下是我用于批量索引编制的代码。 public ActionResult Cr
我正在尝试使用带有格式文件的 BULK INSERT 将 .CSV 文件导入到 SQL Server 表中。我可以导入它,但任何拉丁字符都会作为奇怪的字符导入。我为自己完成这个个人项目感到非常自豪,但
我试图找出为什么我使用的 BULK INSERT 命令无法识别该命令中使用的 FORMAT 和 FIELDQUOTE 选项。 BULK INSERT dbo.tblM2016_RAW_Current_
我是一名优秀的程序员,十分优秀!