Python實(shí)現(xiàn)數(shù)據(jù)庫(kù)并行讀取和寫(xiě)入實(shí)例
這篇主要記錄一下如何實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的并行運(yùn)算來(lái)節(jié)省代碼運(yùn)行時(shí)間。語(yǔ)言是Python,其他語(yǔ)言思路一樣。
前言
一共23w條數(shù)據(jù),是之前通過(guò)自然語(yǔ)言分析處理過(guò)的數(shù)據(jù),附一張截圖:

要實(shí)現(xiàn)對(duì)news主體的讀取,并且找到其中含有的股票名稱(chēng),只要發(fā)現(xiàn),就將這支股票和對(duì)應(yīng)的日期、score寫(xiě)入數(shù)據(jù)庫(kù)。
顯然,幾十萬(wàn)條數(shù)據(jù)要是一條條讀寫(xiě),然后在本機(jī)上操作,耗時(shí)太久,可行性極低。所以,如何有效并行的讀取內(nèi)容,并且進(jìn)行操作,最后再寫(xiě)入數(shù)據(jù)庫(kù)呢?
并行讀取和寫(xiě)入
并行讀?。簞?chuàng)建N*max_process個(gè)進(jìn)程,對(duì)數(shù)據(jù)庫(kù)進(jìn)行讀取。讀取的時(shí)候應(yīng)該注意:
- 每個(gè)進(jìn)程需要分配不同的connection和對(duì)應(yīng)的cursor,否則數(shù)據(jù)庫(kù)會(huì)報(bào)錯(cuò)。
- 數(shù)據(jù)庫(kù)必須能承受相應(yīng)的高并發(fā)訪問(wèn)(可以手動(dòng)更改)
實(shí)現(xiàn)的時(shí)候,如果不在進(jìn)程里面創(chuàng)建新的connection,就會(huì)發(fā)生沖突,每個(gè)進(jìn)程拿到權(quán)限后,會(huì)被下個(gè)進(jìn)程釋放,所以匯報(bào)出來(lái)NoneType Error的錯(cuò)誤。
- 并行寫(xiě)入:在對(duì)數(shù)據(jù)庫(kù)進(jìn)行更改的時(shí)候,不可以多進(jìn)程更改。所以,我們需要根據(jù)已有的表,創(chuàng)建max_process-1個(gè)同樣結(jié)構(gòu)的表用來(lái)寫(xiě)入。表的命名規(guī)則可以直接在原來(lái)基礎(chǔ)上加上1,2,3...數(shù)字可以通過(guò)對(duì)max_process取余得到。
此時(shí),對(duì)應(yīng)進(jìn)程里面先后出現(xiàn)讀入的conn(保存消息后關(guān)閉)和寫(xiě)入的conn。每個(gè)進(jìn)程對(duì)應(yīng)的表的index就是 主循環(huán)中的num對(duì)max_process取余(100->4,101->5),這樣每個(gè)進(jìn)程只對(duì)一個(gè)表進(jìn)行操作了。
部分代碼實(shí)現(xiàn)
max_process = 16 #最大進(jìn)程數(shù)
def read_SQL_write(r_host,r_port,r_user,r_passwd,r_db,r_charset,w_host,w_port,w_user,w_passwd,w_db,w_charset,cmd,index=None):
#得到tem字典保存著信息
try:
conn = pymysql.Connect(host=r_host, port=r_port, user=r_user, passwd =r_passwd, db =r_db, charset =r_charset)
cursor = conn.cursor()
cursor.execute(cmd)
except Exception as e:
error = "[-][-]%d fail to connect SQL for reading" % index
log_error('error.log',error)
return
else:
tem = cursor.fetchone()
print('[+][+]%d succeed to connect SQL for reading' % index)
finally:
cursor.close()
conn.close()
try:
conn = pymysql.Connect(host=w_host, port=w_port, user=w_user, passwd =w_passwd, db =w_db, charset =w_charset)
cursor = conn.cursor()
cursor.execute(cmd)
except Exception as e:
error = "[-][-]%d fail to connect SQL for writing" % index
log_error('error.log',error)
return
else:
print('[+][+]%d succeed to connect SQL for writing' % index)
r_dict = dict()
r_dict['id'] = tem[0]
r_dict['content_id'] = tem[1]
r_dict['pub_date'] = tem[2]
r_dict['title'] = cht_to_chs(tem[3])
r_dict['title_score'] =tem[4]
r_dict['news_content'] = cht_to_chs(tem[5])
r_dict['content_score'] = tem[6]
for key in stock_dict.keys():
#能找到對(duì)應(yīng)的股票
if stock_dict[key][1] and ( r_dict['title'].find(stock_dict[key][1])!=-1 or r_dict['news_content'].find(stock_dict[key][1])!=-1 ):
w_dict=dict()
w_dict['code'] = key
w_dict['english_name'] = stock_dict[key][0]
w_dict['cn_name'] = stock_dict[key][1]
#得到分?jǐn)?shù)
if r_dict['title_score']:
w_dict['score']=r_dict['title_score']
else:
w_dict['score']=r_dict['content_score']
#開(kāi)始寫(xiě)入
try:
global max_process
cmd = "INSERT INTO dyx_stock_score%d VALUES ('%s', '%s' , %d , '%s' , '%s' , %.2f );" % \
(index%max_process ,r_dict['content_id'] ,r_dict['pub_date'] ,w_dict['code'] ,w_dict['english_name'] ,w_dict['cn_name'] ,w_dict['score'])
cursor.execute(cmd)
conn.commit()
except Exception as e:
error = " [-]%d fail to write to SQL" % index
cursor.rollback()
log_error('error.log',error)
else:
print(" [+]%d succeed to write to SQL" % index)
cursor.close()
conn.close()
def main():
num = 238143#數(shù)據(jù)庫(kù)查詢(xún)拿到的總數(shù)
p = None
for index in range(1,num+1):
if index%max_process==1:
if p:
p.close()
p.join()
p = multiprocessing.Pool(max_process)
r_cmd = ('select id,content_id,pub_date,title,title_score,news_content,content_score from dyx_emotion_analysis where id = %d;' % (index))
p.apply_async(func = read_SQL_write,args=(r_host,r_port,r_user,r_passwd,r_db,r_charset,w_host,w_port,w_user,w_passwd,w_db,w_charset,r_cmd,index,))
if p:
p.close()
p.join()
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- python實(shí)現(xiàn)數(shù)據(jù)寫(xiě)入excel表格
- Python寫(xiě)入數(shù)據(jù)到MP3文件中的方法
- Python基于csv模塊實(shí)現(xiàn)讀取與寫(xiě)入csv數(shù)據(jù)的方法
- python讀取excel指定列數(shù)據(jù)并寫(xiě)入到新的excel方法
- Python3實(shí)現(xiàn)將本地JSON大數(shù)據(jù)文件寫(xiě)入MySQL數(shù)據(jù)庫(kù)的方法
- Python實(shí)現(xiàn)自定義順序、排列寫(xiě)入數(shù)據(jù)到Excel的方法
- Python實(shí)現(xiàn)將數(shù)據(jù)框數(shù)據(jù)寫(xiě)入mongodb及mysql數(shù)據(jù)庫(kù)的方法
- Python實(shí)現(xiàn)讀寫(xiě)sqlite3數(shù)據(jù)庫(kù)并將統(tǒng)計(jì)數(shù)據(jù)寫(xiě)入Excel的方法示例
- 利用python對(duì)Excel中的特定數(shù)據(jù)提取并寫(xiě)入新表的方法
- Python把csv數(shù)據(jù)寫(xiě)入list和字典類(lèi)型的變量腳本方法
- Python實(shí)現(xiàn)將數(shù)據(jù)寫(xiě)入netCDF4中的方法示例
相關(guān)文章
安裝python依賴(lài)包psycopg2來(lái)調(diào)用postgresql的操作
這篇文章主要介紹了安裝python依賴(lài)包psycopg2來(lái)調(diào)用postgresql的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
Python利用openpyxl類(lèi)實(shí)現(xiàn)在Excel中繪制樂(lè)高圖案
在商場(chǎng)看到一個(gè)超級(jí)瑪麗的樂(lè)高圖,感覺(jué)使用excel的顏色填充也能畫(huà)出來(lái)。所以本文將借助openpyxl類(lèi)實(shí)現(xiàn)在Excel中繪制樂(lè)高圖案,需要的可以參考一下2022-12-12
Python3和pyqt5實(shí)現(xiàn)控件數(shù)據(jù)動(dòng)態(tài)顯示方式
今天小編就為大家分享一篇Python3和pyqt5實(shí)現(xiàn)控件數(shù)據(jù)動(dòng)態(tài)顯示方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
Python實(shí)現(xiàn)的對(duì)一個(gè)數(shù)進(jìn)行因式分解操作示例
這篇文章主要介紹了Python實(shí)現(xiàn)的對(duì)一個(gè)數(shù)進(jìn)行因式分解操作,結(jié)合實(shí)例形式分析了Python因式分解數(shù)值運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2019-06-06
Python數(shù)據(jù)結(jié)構(gòu)與算法之圖的最短路徑(Dijkstra算法)完整實(shí)例
這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)與算法之圖的最短路徑(Dijkstra算法),結(jié)合完整實(shí)例形式分析了Python圖的最短路徑算法相關(guān)原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-12-12
python中的代碼編碼格式轉(zhuǎn)換問(wèn)題
本文給大家講解的是使用Python實(shí)現(xiàn)代碼編碼格式轉(zhuǎn)換的問(wèn)題,十分的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下。2015-06-06
python實(shí)現(xiàn)在sqlite動(dòng)態(tài)創(chuàng)建表的方法
這篇文章主要介紹了python實(shí)現(xiàn)在sqlite動(dòng)態(tài)創(chuàng)建表的方法,涉及Python操作SQLite數(shù)據(jù)庫(kù)創(chuàng)建數(shù)據(jù)表的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-05-05

