gspread.exceptions.APIError: APIError: [400]: Invalid

최지웅·2025년 9월 19일

RECO

목록 보기
5/10

오류의 원인은 구글 시트 자체의 동작 방식인데, 새 워크시트를 만들면 기본적으로 1000개의 행을 생성한다. 즉 데이터는 1행밖에 없어도 999개의 빈 행을 있다고 인식한다.

이 상태에서 delete_rows나 resize를 통해 행을 1000개 미만으로 줄이려고 하면 '고정되지 않은 모든 행을 삭제할 수 없다'는 오류를 보내 시트의 손상 혹은 비정상적인 상태를 안전장치로서 막아준다.

이를 해결하기 위한 방법으로 아예 새로운 시트를 만드는 방법이 있다.

동작 방식:
기존 시트에서 헤더 데이터만 읽기
완전히 새로운 워크시트를 만들기
새 워크시트의 첫 행에 헤더를 붙여넣기
기존의 문제가 있던 워크시트를 삭제하기
(선택) 새로 만든 워크시트의 이름을 원래 시트 이름으로 변경하기

이 방법은 시트의 숨겨진 상태나 설정에 전혀 영향을 받지 않고, 언제나 깨끗한 상태에서 시작하기 때문에 안정적으로 동작한다.

import gspread

# --- 초기 설정 (본인 환경에 맞게 수정) ---
# gc = gspread.service_account()
# spreadsheet = gc.open("YourSpreadsheetName")
# old_worksheet_name = "Sheet1" # 문제가 발생하는 시트 이름
# ------------------------------------

try:
    # 1. 기존 시트에서 헤더 데이터만 읽어오기
    old_worksheet = spreadsheet.worksheet(old_worksheet_name)
    header = old_worksheet.row_values(1)
    
    # 2. 새로운 워크시트 생성 (이름은 임시로 정함)
    new_worksheet_name = "temp_sheet_for_reset"
    new_worksheet = spreadsheet.add_worksheet(title=new_worksheet_name, rows=1, cols=len(header))
    
    # 3. 새 워크시트의 첫 행에 헤더 붙여넣기
    new_worksheet.append_row(header)
    
    # 4. 기존의 문제가 있던 워크시트 삭제
    spreadsheet.del_worksheet(old_worksheet)
    
    # 5. 새로 만든 워크시트의 이름을 원래 시트 이름으로 변경
    new_worksheet.update_title(old_worksheet_name)
    
    print(f"'{old_worksheet_name}' 시트를 성공적으로 초기화했습니다.")

except gspread.exceptions.WorksheetNotFound:
    print(f"'{old_worksheet_name}' 시트를 찾을 수 없습니다.")
except Exception as e:
    print(f"오류가 발생했습니다: {e}")

조금 복잡해 보일 수 있지만, 이 방법은 구글 시트 API의 제약사항을 완전히 우회하여 어떤 상황에서도 헤더만 남기고 시트를 깨끗하게 초기화할 수 있는 가장 확실한 방법이다.

물론 나는 그냥 데이터 삭제만 수행했다. 굳이 행을 삭제할 필요는 없기에.. 종종 해주시겠지? 혹은 max로 차거나 하면 문제가 되겠지만 어차피 매일매일 쓸거라.. 크게 데이터 누적도 없을거고 수동으로 시트 행 삭제도 가능하다.

profile
이제 4학년!!!

0개의 댓글