본문 바로가기
IT/Data Analysis

[python oracle] oracledb insert할 때 execute, executemany 안되는 에러

by 한동두 2025. 7. 10.
반응형

방금까지 잘 들어가던 insert 코드인데

갑자기 에러도 안나고 무한 대기일 때 해결해 볼 만한 내용을 소개하도록 하겠다.

결과만 필요하신 분들은 3번으로 가세요!

 


1. 문제 상황

데이터가 잘 되나  insert해 봤는데 잘 돼서

잘 되는거 확인하고 db비워주고 다시 insert 실행해봤는데 안된다.

잘 되던거라 코드가 잘못된 건 아닐텐데!!!!

 

 


2. 코드

일단  간단하게 내가 어떤 방법으로 insert 하고있었는지 적어보겠다..!!

 

def insert_rows(con, merge_df):
    rows = [tuple(row) for row in merge_df.itertuples(index=False, name=None)]
    columns = list(merge_df.columns)
    placeholders = ", ".join([f":{i+1}" for i in range(len(columns))])
    sql = f"INSERT INTO 테이블명 ({', '.join(columns)}) VALUES ({placeholders})"
    cur = con.cursor()
    cur.executemany(sql, rows)
    con.commit()
    cur.close()
    
def db_connection():
    username = "id"
    password = "pw"
    ip = "db_ip"
    port = "db_port" #default 1521인듯
    service="service명"

    con = oracledb.connect(
        user=username,
        password=password,
        dsn=f"{ip}:{port}/{service}"
    )
    print("Successfully connected to Oracle Database")
    return con
    
if __name__ == "__main__":
    dataPath = "/my/data/path"
    my_list = os.listdir(dataPath)
    my_list = sorted(my_list)
    #my_list = ["100"] #테스트로 사용했었다.
    #db연결
    con = db_connection()

    for i in my_list:
        print(i)
        for y in range(1990, 2020):
            merge_df = pd.DataFrame(columns=["column", "lists"])
            for m in range(1,13):
                month_str = f"{m:02d}"  # 2자리
                # df 계속 쌓아주는 역할. 1년치 데이터를 모아준다.
                # make_row : merge_df와 같은 모양의 df(1줄짜리)를 만들어내는 함수 
                merge_df = pd.concat([merge_df, make_row(dataPath, i, y, m, month_str)], ignore_index=True )
            insert_rows(con, merge_df)
            print(f"{i}_{y}_insertRow success")
	con.close()

대충 이렇게 했었다.
i가 800개 정도 되고, year정보랑 month정보 이용하여 1년단위로 df를 만든 후 해당 df의 row를 일괄로 insert하는 코드였다.

 

테스트용으로 i=100으로, y=1990으로, m=1로 했을때 분명히 insert에 성공한 것을 확인하였다.

sql developer로 delete from 테이블명 해서 지워주었다.(데이터 겹치면 안되니까)

 

이후 전체 다 돌리기 위해서 전체 for문으로 수행하였더니 딱 cur.executemany(sql, rows)에서 안되는 문제가 발생했다.

 


3. 해결방법

혹시 session문젠가 해서 세션도 삭제해봤는데 해결이 안됐고

(참고 : 세션 삭제 sql문)

더보기
SELECT
    sid,
    serial#,
    username,
    status,
    osuser,
    machine,
    program,
    TO_CHAR(logon_time, 'YYYY-MM-DD HH24:MI:SS')
FROM
    v$session
WHERE
    username = '사용자명';
    
    
<!-- 조회 결과 이용하여 아래 코드 실행 -->
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;

어쩌다보니 다른 i, y, m으로 테스트 해봤더니 엥? 들어가는것이아닌가

 

결과적으로 python코드에는 문제가 없었고...

delete하는 과정에서 문제가있었다.

 

delete하고 난 뒤 반영할 때는 commit을 꼭 해줘야한다!!!!!!!!!!!

나는 심지어 delete하고 commit도 했다고 생각했는데

 

delete from table명

commit;
이렇게 두줄 블럭잡아서 컨트롤엔터 했었는데

이렇게 하면 commit을 인식을 못할수도 있단다......!!!

 

delete 뒤에 세미콜론을 꼭 해줘야하며 차라리 그냥 따로따로 두번 실행을 하는것이 더 정확하게 동작할 수 있다.

 

delete from table명;

commit;

이렇게 해주면 쿼리 처리 결과에 커밋완료라고 뜰 것이다...

커밋완료라고 떠야지 진짜 delete된 것이다.

 

 

나의 경우 delete만 되고 commit은 안되고있었던 것이다... (위에 delete 2번 시도 한 이후로 계속 insert가 안됐었다)

나는 분명히 commit을 실행시켰다고 생각햇는데 실행이 안되었던 것이다ㅠㅠ.

혹시 코드 문제는 아닌데 delete후  아무리해도 insert가 안되는 경우 commit을 해보길 바란다...!!

 

진짜 별거아닌데 이거로 2시간 넘게 헤맸다..

분명히 select * from table명 했을 때는 안나오니까....

아무래도 mysql만 주로 해봤지 oracle을 해본 경험이 없었던 것도 그렇고..

oracle에 대한 지식이 너무 없어서 그랬던 것 같아 다시한번 반성하게 되었다..

 

 

반응형