python 용량이 큰 dataframe을 mssql에 빠르게 insert할 수 있는 방법이 뭔가요?

조회수 3304회

python의 pandas로 데이터프레임을 만들고 mssql에 insert하려는데 데이터프레임이 평균적으로 25만 rows에 14컬럼으로 형성됩니다.

sqlalchemy.create_engine으로 sql형태로 전체를 insert하는 방법을 해보니 로컬에서는 45분이 걸렸고, dataframe.iterrows()를 통해 반복문으로 cursor.execute() 한 라인씩 insert하니 이것 또한 오래걸려서 현재 실행중입니다..

데이터프레임 가공하는 것에는 10초도 걸리지 않는데 어떻게해야 mssql에 빠르게 insert할 수 있을까요?

json파일 중 가장 큰 용량 파일은 316,650KB입니다.

  • https://docs.microsoft.com/ko-kr/sql/relational-databases/import-export/import-bulk-data-by-using-bulk-insert-or-openrowset-bulk-sql-server?view=sql-server-ver15 정영훈 2020.6.19 09:00
  • 쿼리문을 insert into TABLES(a,b) values (a,b), (c,d), (e,f), (g,h).... 으로 하면 빨리 입력되긴 합니다. 체감될정도로요.. 김호원 2020.6.19 09:04
  • csv file의 데이터를 (a,b), (c,d), (e,f), (g,h)형태로 읽어드리려면 어떻게 해야하나요,,, 김재민 2020.6.19 10:06
  • 특정 n개수 row를 묶으셔서 mssql 에 insert 할때 위에 형태로 하시면 보다 빨라요. 아니면 정영훈님 댓글처럼 csv bulk insert 하셔도 될듯.. 그것도 아니면 mssql 관리툴? 있는걸로 아는데 csv import 해보시는것도.. 김호원 2020.6.19 10:42
  • bulk 할 때 csv파일을 경로 설정하듯이 주던데 경로가 아니라 데이터프레임 또는 reader 된 csv파일 변수를 적용시켜서 할 수는 없을까요? 김재민 2020.6.19 11:16
  • 1회성 아닌가요? 그렇다면 local에 csv 로 생성하고 bulk insert 를 하는편이 낫습니다. bulk 작업시에 꼭 확인해야 하는 것이 오류케이스입니다. 오류발생하면 rollback 되는데 차라리 파일단위로 잘라놓으면 오류수정하기가 용이하겠죠 정영훈 2020.6.19 12:05
  • 한줄의 insert 구문으로 만들려면 dataframe 의 데이터를 잘라서 만들어야 합니다. 그러는 이유 역시 오류케이스 때문이구요. 만건씩 잘라서 insert 구문으로 만들어서 수행하는 형태도 괜찮습니다. 정영훈 2020.6.19 12:09
  • cursor.execute(bulk insert tableName FROM 'C:/Users/user/Desktop/OnSpark/data/test.csv' WITH(FORMAT='CSV', FIELDTERMINATOR =',', ROWTERMINATOR ='\n')) 로 진행했지만 김재민 2020.6.19 12:56
  • Cannot bulk load because the file "C:/Users/user/Desktop/OnSpark/data/test.csv" could not be opened. Operating system error code (null).와 같은 오류가 발생합니다. 어디를 수정해야할까요? 김재민 2020.6.19 12:57

2 답변

  • 좋아요

    1

    싫어요
    채택 취소하기
    import pandas as pd
    import pymysql
    import time
    
    def makefile(name,q):
        f = open(name,'w')
        f.write('ls,num,id,pass,name\n')
        for i in range(q):
            txt = '%s,%s,id%s,pw%s,nm%s\n'%(i,i,i,i,i)
            f.write(txt)
    
    def conn():
        db = pymysql.connect(host='localhost',port=3306,user='howoni',passwd='#',db='howoni')
        c = db.cursor()
        c.execute('truncate TABLES')
        return db
    
    makefile('hi2.csv',500000)
    df = pd.read_csv('hi2.csv',index_col='ls')
    
    b = conn()
    a = b.cursor()
    
    s = time.time()
    sql = 'insert into TABLES values '
    data = []
    for idx, i in enumerate(df.values):     
        sql += '(%s, %s, %s, %s),'
        for j in i:
            data.append(j)
        if idx % 20 == 0:
            sql = sql.rstrip(',')
            a.execute(sql, tuple(data))
            sql = 'insert into TABLES values '
            data = []
    sql = sql.rstrip(',')
    a.execute(sql,data)
    print(time.time()-s)
    
    s = time.time()
    sql = 'insert into TABLES values (%s, %s, %s, %s)'
    for i in df.values:
        a.execute(sql, tuple(i))
    print(time.time()-s)
    
    a.execute('select count(*) from TABLES')
    r = a.fetchone()
    print(r)
    
    b.commit()
    a.close()
    

    1) "insert into [TABLES] values (%s, %s, %s, %s) * 20" * 25000 : 500000rows 소요시간 15초,

    2) "insert into [TABLES] values (%s, %s, %s, %s) * 500000 : 500000rows 소요시간 120초

    pymssql이용해서 bulk가 아닌방법으로 때려박으실때 참고하시면될거같아용

    • bulk입력을 실패했는데 덕분에 해당 방법으로 성공했습니다! 감사합니다. 김재민 2020.6.19 16:06
  • stackoverflow 에도 같은 질문 타래가 있네요. 다양한 답변이 달렸으니, 한번 테스트해 보시길.

    https://stackoverflow.com/questions/29706278/python-pandas-to-sql-with-sqlalchemy-how-to-speed-up-exporting-to-ms-sql

    • 감사합니다!! 김재민 2020.6.19 16:06

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)