Python學習筆記-SQLSERVER的大批量導入以及平常操做(比executemany快3倍)

環境 : python3.6 / win10 / vs2017 / sqlserver2017html

1、須要安裝的包pymssqlpython

pip install pymssql

2、pymssql模塊的介紹sql

pymssql 包 有modules:app

  • pymssql – 若是您關注DB-API聽從性,或者若是您習慣於DB-API語法,請使用它。
  • _mssql –  比pymssql更高性能和易用性,性能高出不是一點點,用法也相對簡單。

因此我更加推薦使用_mssql,而不是網上案列裏比較多的pymssql函數

3、對_mssql模塊的封裝sqlserver

一、簡單的執行性能

class C_SQLServer(object): def __init__(self, Server,user,password,database): self.Server=Server self.user=user self.password=password self.database=database #執行無返回操做,適用與(insert,update,delete)
    def execute_non_query(self,SQLStr): conn = _mssql.connect(server=self.Server, user=self.user, password=self.password, database=self.database,charset='utf8') conn.execute_non_query(SQLStr) #執行返回迭代器的操做,迭代器中的行以字典方式展現,適用於(select)
    def execute_query(self,SQLStr): conn = _mssql.connect(server=self.Server, user=self.user, password=self.password, database=self.database,charset='utf8') conn.execute_query(SQLStr) return conn #執行返回單行的字典
    def execute_row(self,SQLStr): conn = _mssql.connect(server=self.Server, user=self.user, password=self.password, database=self.database,charset='utf8') row=conn.execute_row(SQLStr) return row #執行返回單值的操做,適用於返回行計數等
    def execute_scalar(self,SQLStr): conn = _mssql.connect(server=self.Server, user=self.user, password=self.password, database=self.database,charset='utf8') scalar=conn.execute_scalar(SQLStr) return scalar #獲取標題,以及標題類型字典
    def MSSQL_GetTitleDict(self,conn): titleDict={} for rows in conn.get_header(): titleDict[rows[0]]=rows[1]
     #若是調用conn完成後千萬記得,要吧鏈接關閉。
     conn.close()
return titleDict

4、對於大批量Insert的操做測試

pymssql的模塊提供了executemany來執行大批量的導入。spa

導入列表裏的元素行爲Tuple,相似 DataList=[(1,2),(2,3)]scala

cursor.executemany( "INSERT INTO persons VALUES (%d, %s, %s)", [(1, 'John Smith', 'John Doe'), (2, 'Jane Doe', 'Joe Dog'), (3, 'Mike T.', 'Sarah H.')]) # you must call commit() to persist your data if you don't set autocommit to True
conn.commit()

_mssql模塊沒有提供批量導入的功能。

可是咱們能夠用拼接字符串 Insert ————Select————UNION ALL————SELECT 去實現。

測通過測試,一樣插入10W的數據,_mssql模塊寫拼接比pymssql的executemany快了近3倍多。

代碼以下:

def GetTableTitle(self,tableName): SQLStr=f"select * from {tableName}" conn=self.execute_query(f"select * from {tableName}") titleDict=self.MSSQL_GetTitleDict(conn) return titleDict

#拼接字符串 Insert ————Select————UNION ALL————SELECT類型插入 def InsertByRow(self,tableName,TitleList,DataList): #獲取列頭的字典包含列名以及數據類型 titleDict=self.GetTableTitle(tableName) #定義Insert語句的頭部 insertTitleStr=f"Insert into {tableName} (" + ','.join(TitleList)+")\n" #批導入變量,執行行號 i=0 #按行執行 for row_dict in DataList: insertRowStrList=[] #循環列 for columnName in TitleList: columnType=titleDict[columnName] if columnType in [1,4]: isChar=1 else: isChar=0 columValue= row_dict[columnName] #SqlParameter_AddQuotes函數用以增給值增長單引號 columValue=SqlParameter_AddQuotes(isChar,columValue) queryStr=columnName+"="+columValue insertRowStrList.append(queryStr) #行的SelectStr insertRowStr=','.join(insertRowStrList) if i==0: insertStr="Select "+insertRowStr else: insertStr+="\n union all \nSelect "+insertRowStr i+=1 #定義批量插入的大小,這裏是300行爲一批Insert if i%300==0: self.execute_non_query(insertTitleStr+'\n'+insertStr) i=0 #剩餘數據Insert self.execute_non_query(insertTitleStr+'\n'+insertStr)

 

 性能剛剛的!平常的操做基本也就都封裝好了!

 可是記得打開conn後,千萬必需要關閉該鏈接。

相關文章
相關標籤/搜索