記錄一次讀取 9.8G的一個csv文件,並且寫入mysql。

記錄一次讀取1600萬 行 X 41列的csv文件。

目標 /環境

文件數據爲測試模擬數據,數據大小 9.8G,目標爲讀取數據,並且寫入mysql。
目標文件
目標文件

運行環境:

python3.6 (64位),pandas,pymysql。

思路

採用pandas內置read_csv方法,分塊讀取文件,開4個進程寫入mysql。

遇到的坑有,memoryerror,這裏需要強調!!! 必須把寫入過的數據del掉,然後調用gc.collect() 釋放內存,否則,一直會出現memoryerror,因爲python的垃圾回收機制必須試函數執行完才釋放,按照這個思路,不等數據讀取完,內存就炸了。

下面上代碼。

代碼

import pandas as pd
from sqlalchemy import create_engine
from multiprocessing import Pool
import gc

def gets():
    """分塊讀取文件,其實1,000,000行據說速度最佳。"""
    df1 = pd.read_csv(r'C:\\Users\\zq\\Desktop\\Project\\demo_python\\測試2.csv', low_memory=False, chunksize=500000)
    return df1

def to_sqls(df, table):
    """寫入mysql"""
    engine = create_engine('mysql+pymysql://root:[email protected]:3306/demo',
                           max_overflow=0, pool_size=5,
                           pool_timeout=30, pool_recycle=-1)
    con = engine.connect()
    df.to_sql(table, con=con, if_exists='append')
    del df#刪除掉變量,釋放內存。
    gc.collect()

def get_times():
    p = Pool(4)
    df = gets()
    for df1 in df:
        print(df1.shape[0])
        for i in range(0, df1.shape[0] + 1, int((df1.shape[0] + 1) / 4)):

            if (i + int((df1.shape[0] + 1) / 4)) < (df1.shape[0] + 1):

                p.apply_async(to_sqls, args=(df1.iloc[i:i + int((df1.shape[0] + 1) / 4), :], 'ce'))
            else:#超出文件範圍
                p.apply_async(to_sqls, args=(df1.iloc[i:df1.shape[0] + 1, :], 'ce'))

	p.close()
    p.join()


if __name__ == '__main__':
    import time
	t1 = time.time()
    get_times()
    t2 = time.time() - t1
    print('%s s' % t2)

結果。

實際測試時間爲:1161.214187860489 s完成整個程序。(包含讀取 和寫入)
在這裏插入圖片描述
數據庫結果如下。
在這裏插入圖片描述
本次記錄到此。如果後期發現更快的方法,將繼續分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章