我正在寻找帮助将.csv文件导入SQL Server使用BULK INSERT,我几乎没有基本问题.
问题:
CSV文件数据之间可能有,(逗号)(例如:描述),那么如何进行导入处理这些数据呢?
如果客户端从Excel创建CSV,那么带有逗号的数据将包含在""(双引号)[如下例]中,那么导入如何处理呢?
我们如何跟踪某些行是否包含导致跳过的错误数据?(导入是否会跳过不可导入的行)
以下是带标题的示例CSV:
Name,Class,Subject,ExamDate,Mark,Description
Prabhat,4,Math,2/10/2013,25,Test data for prabhat.
Murari,5,Science,2/11/2013,24,"Test data for his's test, where we can test 2nd ROW, Test."
sanjay,4,Science,,25,Test Only.
Run Code Online (Sandbox Code Playgroud)
和要导入的SQL语句:
BULK INSERT SchoolsTemp
FROM 'C:\CSVData\Schools.csv'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = ',', --CSV field delimiter
ROWTERMINATOR = '\n', --Use to shift the control to next row
TABLOCK
)
Run Code Online (Sandbox Code Playgroud) 我想发送一个大型pandas.DataFrame到运行MS SQL的远程服务器.我现在的方法是将data_frame对象转换为元组列表,然后使用pyODBC的executemany()函数将其发送出去.它是这样的:
import pyodbc as pdb
list_of_tuples = convert_df(data_frame)
connection = pdb.connect(cnxn_str)
cursor = connection.cursor()
cursor.fast_executemany = True
cursor.executemany(sql_statement, list_of_tuples)
connection.commit()
cursor.close()
connection.close()
Run Code Online (Sandbox Code Playgroud)
然后我开始怀疑使用data_frame.to_sql()方法是否可以加速(或至少更具可读性).我想出了以下解决方案:
import sqlalchemy as sa
engine = sa.create_engine("mssql+pyodbc:///?odbc_connect=%s" % cnxn_str)
data_frame.to_sql(table_name, engine, index=False)
Run Code Online (Sandbox Code Playgroud)
现在代码更具可读性,但上传速度至少慢150倍 ......
有没有办法fast_executemany在使用SQLAlchemy时翻转?
我正在使用pandas-0.20.3,pyODBC-4.0.21和sqlalchemy-1.1.13.
我有一些相当大的pandas DataFrames,我想使用新的批量SQL映射通过SQL Alchemy将它们上传到Microsoft SQL Server.pandas.to_sql方法虽然不错,但速度很慢.
我在编写代码时遇到了麻烦......
我希望能够将这个函数传递给我正在调用的pandas DataFrame,我正在调用table的模式名称schema,以及我正在调用的表名name.理想情况下,该函数将1.)删除表,如果它已经存在.2.)创建一个新表3.)创建一个mapper和4.)使用mapper和pandas数据批量插入.我被困在第3部分.
这是我的(诚然粗糙的)代码.我正在努力解决如何让mapper函数与我的主键一起工作.我真的不需要主键,但映射器功能需要它.
感谢您的见解.
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
Run Code Online (Sandbox Code Playgroud) 有了这个表:
CREATE TABLE test_insert (
col1 INT,
col2 VARCHAR(10),
col3 DATE
)
Run Code Online (Sandbox Code Playgroud)
以下代码需要40秒才能运行:
import pyodbc
from datetime import date
conn = pyodbc.connect('DRIVER={SQL Server Native Client 10.0};'
'SERVER=localhost;DATABASE=test;UID=xxx;PWD=yyy')
rows = []
row = [1, 'abc', date.today()]
for i in range(10000):
rows.append(row)
cursor = conn.cursor()
cursor.executemany('INSERT INTO test_insert VALUES (?, ?, ?)', rows)
conn.commit()
Run Code Online (Sandbox Code Playgroud)
psycopg2的等效代码只需3秒.我不认为mssql比postgresql慢得多.有关如何在使用pyodbc时提高批量插入速度的任何想法?
编辑:在ghoerz发现之后添加一些注释
在pyodbc中,流程executemany是:
在ceODBC,流程executemany是:
我有一个大约155,000行和12列的数据帧.如果我使用dataframe.to_csv将其导出到csv,则输出为11MB文件(即时生成).
但是,如果我使用to_sql方法导出到Microsoft SQL Server,则需要5到6分钟!没有列是文本:只有int,float,bool和日期.我见过ODBC驱动程序设置nvarchar(max)的情况,这会减慢数据传输速度,但这不是这种情况.
有关如何加快出口流程的任何建议?导出11 MB数据需要6分钟,这使得ODBC连接几乎无法使用.
谢谢!
我的代码是:
import pandas as pd
from sqlalchemy import create_engine, MetaData, Table, select
ServerName = "myserver"
Database = "mydatabase"
TableName = "mytable"
engine = create_engine('mssql+pyodbc://' + ServerName + '/' + Database)
conn = engine.connect()
metadata = MetaData(conn)
my_data_frame.to_sql(TableName,engine)
Run Code Online (Sandbox Code Playgroud) 在python脚本中,我需要在一个数据源上运行查询,并将该查询中的每一行插入到不同数据源的表中.我通常使用带有tsql链接服务器连接的单个insert/select语句来执行此操作,但是我没有与此特定数据源的链接服务器连接.
我找不到一个简单的pyodbc示例.这是我怎么做的,但我猜测在循环中执行一个插入语句非常慢.
result = ds1Cursor.execute(selectSql)
for row in result:
insertSql = "insert into TableName (Col1, Col2, Col3) values (?, ?, ?)"
ds2Cursor.execute(insertSql, row[0], row[1], row[2])
ds2Cursor.commit()
Run Code Online (Sandbox Code Playgroud)
使用pyodbc插入记录有更好的批量方式吗?或者这是一种相对有效的方法来做到这一点.我正在使用SqlServer 2012,以及最新的pyodbc和python版本.
我正在使用python和sql数据库的第一步,仍然不确定使用哪个包以及如何使用.我有一个大约300k字典的列表,每个字典大约有20个键.这些dicts应插入SQL表中.
在我看来,dict方法列表的优点是,我明确地命名了我想要输入特定值的列.(可能是,这不是一个好方法)
让我提出一个更具体的例子来捕捉我的问题的基本要素.该表由三列组成:ID(整数),Price(十进制),Type(字符串).Type支持空值.
我的dict的键具有相同的名称,而dicts列表可能如下所示:
lst = [{'ID':1, 'Price': '9.95', 'Type': None},
{'ID':2, 'Price': '7.95', 'Type': 'Sports'},
{'ID':3, 'Price': '4.95', 'Type': 'Tools'}, ...]
Run Code Online (Sandbox Code Playgroud)
所以出现的问题如下:
在 中python,我有一个从一个数据库 ( Redshiftvia psycopg2) 中选择数据的过程,然后将该数据插入SQL Server(via pyodbc)。我选择进行读/写而不是读/平面文件/加载,因为每天的行数约为 100,000。似乎更容易简单地连接和插入。但是 - 插入过程很慢,需要几分钟。
有没有更好的方法使用 Pyodbc 将数据插入 SQL Server?
select_cursor.execute(output_query)
done = False
rowcount = 0
while not done:
rows = select_cursor.fetchmany(10000)
insert_list = []
if rows == []:
done = True
break
for row in rows:
rowcount += 1
insert_params = (
row[0],
row[1],
row[2]
)
insert_list.append(insert_params)
insert_cnxn = pyodbc.connect('''Connection Information''')
insert_cursor = insert_cnxn.cursor()
insert_cursor.executemany("""
INSERT INTO Destination (AccountNumber, OrderDate, Value)
VALUES (?, ?, ?) …Run Code Online (Sandbox Code Playgroud) python ×6
pyodbc ×5
sql-server ×4
sql ×3
sqlalchemy ×3
bulkinsert ×2
pandas ×2
bulk ×1
csv ×1
python-3.x ×1