Notion API + Python으로 데이터베이스 자동 생성하기

대상: Notion을 “수동 입력용 문서”가 아니라, Python 스크립트로 DB를 자동 생성/관리하고 싶은 개발자
환경:

  • Notion 계정 + 워크스페이스
  • Notion API(Integration) 사용 권한
  • Python 3.8+
  • 라이브러리: notion-client, python-dotenv

1. 문제/주제 요약

  • Notion에서 매번 “새 데이터베이스 → 컬럼 추가 → 옵션 설정” 하는 게 귀찮다
  • Python 코드로 특정 페이지 아래에 DB를 자동 생성하고 싶다
  • 나아가 나중에는 이 DB에 row(페이지)를 자동으로 추가/수정하는 자동화도 하고 싶다

이 글에서는 다음을 목표로 합니다.

  1. Notion Integration 생성 후 Python에서 API 연결
  2. notion-client를 이용해 새 데이터베이스를 자동 생성
  3. 생성된 DB에 간단한 아이템(페이지) 하나까지 추가하는 예제

2. 배경/원리 설명

2-1. Notion API 동작 방식 간단 정리

  • Notion의 공식 REST API는 Integration(연결)을 통해 워크스페이스에 접근합니다.
  • Integration을 만들면 Secret Token을 발급받고, 이 토큰으로 HTTP 요청을 보냅니다. (Notion API Documentation)
  • Python에서는 공식 JS SDK 대신 Python용 클라이언트 라이브러리 notion-client(notion-sdk-py) 를 쓰면 편합니다. (PyPI)

2-2. “데이터베이스 자동 생성”의 핵심

Notion API에서 데이터베이스 생성은 다음과 같이 동작합니다. (Notion API Documentation)

  1. parent: “어느 페이지 아래에 DB를 만들지” 지정
    • parent = { "type": "page_id", "page_id": "<부모 페이지 ID>" }
  2. title: 데이터베이스 이름(리치 텍스트 배열)
  3. properties: 컬럼 스키마 정의
    • 최소 1개의 title 타입 속성이 반드시 필요
    • 예:
      • {"Name": {"title": {}}}
      • "Tags" 컬럼: multi_select
      • "Due" 컬럼: date

Python 클라이언트를 쓰면 이걸 notion.databases.create(...) 한 번으로 호출할 수 있습니다. (Velog)


3. 단계별 설정 및 예제 코드

3-1. Notion Integration 생성 & 토큰 발급

  1. 브라우저에서 Notion → Settings → Connections → Develop or manage integrations로 이동
  2. New integration 클릭 후 이름/권한 설정
  3. 생성 후 나오는 화면에서 Internal Integration Token 복사 (Notion API Documentation)

이 토큰이 나중에 Python 코드의 NOTION_TOKEN이 됩니다.

3-2. Integration에 권한 줄 페이지 준비

  1. Notion에서 DB를 만들고 싶은 위치에 빈 페이지 하나 생성 (예: API 테스트 페이지)
  2. 그 페이지 우측 상단 Share 버튼 클릭 → 방금 만든 Integration을 초대 (Invite)
    • Integration이 초대된 페이지/DB만 API에서 접근 가능
  3. URL에서 page_id를 추출
    • URL 예:
      https://www.notion.so/workspace/API-테스트-페이지-1234567890abcdef1234567890abcdef?pvs=4
    • 여기서 1234567890abcdef1234567890abcdef 부분이 page_id
    • 하이픈이 섞인 경우도 있는데, 보통 라이브러리에서 자동으로 처리해 줍니다. (문송한투자자)

page_id를 나중에 PARENT_PAGE_ID로 사용합니다.

3-3. Python 환경 세팅

필요 라이브러리 설치:

pip install notion-client python-dotenv
  • notion-client: 공식 Notion API용 Python 클라이언트 (PyPI)
  • python-dotenv: .env 파일에서 안전하게 토큰을 불러오기 위함 (Velog)

프로젝트 구조 예:

notion_db_auto_create/
├─ main.py
├─ .env

.env 파일 내용(직접 생성):

NOTION_TOKEN=여기에_발급받은_시크릿_토큰_붙여넣기
NOTION_PARENT_PAGE_ID=여기에_부모_페이지_ID_붙여넣기

3-4. Python에서 Notion 클라이언트 연결

main.py에 기본 연결 코드 작성:

# main.py
import os
from dotenv import load_dotenv
from notion_client import Client

# .env 파일 로드
load_dotenv()

NOTION_TOKEN = os.getenv("NOTION_TOKEN")
PARENT_PAGE_ID = os.getenv("NOTION_PARENT_PAGE_ID")

if NOTION_TOKEN is None or PARENT_PAGE_ID is None:
    raise RuntimeError("NOTION_TOKEN 또는 NOTION_PARENT_PAGE_ID 가 설정되어 있지 않습니다.")

# Notion 클라이언트 생성
notion = Client(auth=NOTION_TOKEN)

여기까지 실행해 보고, 에러 없이 넘어가면 토큰/페이지 ID 설정은 OK입니다.

3-5. 데이터베이스 자동 생성 함수 작성

이제 notion.databases.create()를 이용해서 실제 DB를 만듭니다.
예시: “할 일 관리용 DB”를 자동으로 생성해 보는 코드입니다. (Velog)

def create_todo_database():
    # 데이터베이스 제목 (리치 텍스트 배열)
    title = [
        {
            "type": "text",
            "text": {
                "content": "자동 생성 ToDo DB",
            },
        }
    ]

    # 컬럼(프로퍼티) 정의
    properties = {
        # 필수: title 타입 컬럼 (DB 이름/row 이름 역할)
        "이름": {
            "title": {}
        },
        # 상태 선택(select)
        "상태": {
            "select": {
                "options": [
                    {"name": "Todo", "color": "red"},
                    {"name": "Doing", "color": "yellow"},
                    {"name": "Done", "color": "green"},
                ]
            }
        },
        # 마감일(date)
        "마감일": {
            "date": {}
        },
        # 태그(multi_select)
        "태그": {
            "multi_select": {
                "options": [
                    {"name": "개발", "color": "blue"},
                    {"name": "문서화", "color": "purple"},
                    {"name": "리뷰", "color": "orange"},
                ]
            }
        },
        # 우선순위(number)
        "우선순위": {
            "number": {
                "format": "number"
            }
        },
    }

    # API 호출
    db = notion.databases.create(
        parent={
            "type": "page_id",
            "page_id": PARENT_PAGE_ID,
        },
        title=title,
        properties=properties,
    )

    print("새 데이터베이스 생성 완료!")
    print("DB ID:", db["id"])
    return db["id"]

전체 main.py 예시는 아래와 같이 정리할 수 있습니다.

# main.py
import os
from dotenv import load_dotenv
from notion_client import Client

load_dotenv()

NOTION_TOKEN = os.getenv("NOTION_TOKEN")
PARENT_PAGE_ID = os.getenv("NOTION_PARENT_PAGE_ID")

if NOTION_TOKEN is None or PARENT_PAGE_ID is None:
    raise RuntimeError("NOTION_TOKEN 또는 NOTION_PARENT_PAGE_ID 가 설정되어 있지 않습니다.")

notion = Client(auth=NOTION_TOKEN)


def create_todo_database():
    title = [
        {
            "type": "text",
            "text": {
                "content": "자동 생성 ToDo DB",
            },
        }
    ]

    properties = {
        "이름": {"title": {}},
        "상태": {
            "select": {
                "options": [
                    {"name": "Todo", "color": "red"},
                    {"name": "Doing", "color": "yellow"},
                    {"name": "Done", "color": "green"},
                ]
            }
        },
        "마감일": {"date": {}},
        "태그": {
            "multi_select": {
                "options": [
                    {"name": "개발", "color": "blue"},
                    {"name": "문서화", "color": "purple"},
                    {"name": "리뷰", "color": "orange"},
                ]
            }
        },
        "우선순위": {
            "number": {"format": "number"}
        },
    }

    db = notion.databases.create(
        parent={"type": "page_id", "page_id": PARENT_PAGE_ID},
        title=title,
        properties=properties,
    )

    print("새 데이터베이스 생성 완료!")
    print("DB ID:", db["id"])
    return db["id"]


if __name__ == "__main__":
    create_todo_database()

이 스크립트를 실행하면, PARENT_PAGE_ID로 지정한 페이지 아래에 “자동 생성 ToDo DB” 라는 이름의 DB가 생기고, 설정한 컬럼들이 자동으로 만들어집니다.


3-6. 생성된 DB에 Row(페이지) 자동 추가 예제

“DB만 생기면 끝”보다는, Row까지 하나 넣어보면 전체 흐름을 이해하기 쉽습니다.
DB에 Row를 추가하는 것은 “페이지 생성 + parent를 database_id로 지정”입니다. (Notion API Documentation)

def add_sample_todo(database_id: str):
    new_page = notion.pages.create(
        parent={"database_id": database_id},
        properties={
            "이름": {
                "title": [
                    {
                        "text": {"content": "API로 만든 할 일 1"},
                    }
                ]
            },
            "상태": {
                "select": {"name": "Todo"}
            },
            "마감일": {
                "date": {"start": "2025-11-30"}
            },
            "태그": {
                "multi_select": [
                    {"name": "개발"},
                    {"name": "문서화"},
                ]
            },
            "우선순위": {
                "number": 1
            },
        },
    )

    print("새 Row(페이지) 추가 완료!")
    print("Page ID:", new_page["id"])

main을 조금 수정해서 DB 생성 후 바로 Row를 넣어보면:

if __name__ == "__main__":
    db_id = create_todo_database()
    add_sample_todo(db_id)

이제 스크립트를 실행하면:

  1. 부모 페이지 아래에 ToDo DB가 생성되고
  2. 그 DB 안에 “API로 만든 할 일 1”이라는 Row가 자동으로 들어갑니다.

4. 추가 팁 / 자주 하는 실수

  1. Integration을 페이지에 초대 안 함
    • 토큰만 만들고, 실제 페이지에서 Share → Integration 초대를 안 하면
  2. title 컬럼 누락
    • DB 스키마에서 title 타입 컬럼이 최소 1개는 있어야 합니다.
    • 위 예제에서 "이름": {"title": {}}가 그 역할입니다. 이거 안 넣으면 400 에러. (pynotion.com)
  3. 환경 변수/토큰 하드코딩
    • 직접 코드에 NOTION_TOKEN = "..." 라고 쓰기 시작하면 나중에 깃에 올라가서 사고 납니다.
    • .env + python-dotenv 조합으로 관리하는 습관을 들이는 게 좋습니다. (Velog)
  4. API 버전/스키마 변경
    • Notion API는 2025-09-03 버전 이후 데이터베이스/데이터 소스 분리 등 변경이 진행 중입니다. (Notion API Documentation)
    • 공식 문서 Create a database / Working with databases를 수시로 확인하면서, 프로퍼티 스키마나 엔드포인트가 바뀌었는지 체크하는 것이 안전합니다. (Notion API Documentation)
  5. 대량 호출 시 rate limit
    • 짧은 시간에 너무 많은 DB/페이지를 만들면 429 Too Many Requests가 떨어질 수 있습니다. (Notion API Documentation)
    • 이 경우 time.sleep()으로 간단히 딜레이를 주거나, retry 로직을 넣어야 합니다.

5. 정리

  • Notion API에서는 Integration 토큰 + parent page id만 준비되면, Python에서 notion-client로 손쉽게 데이터베이스를 생성할 수 있습니다. (PyPI)
  • 핵심은 notion.databases.create(parent, title, properties) 호출 시 최소 1개의 title 컬럼과 원하는 속성 스키마를 올바른 JSON 형식으로 넘기는 것입니다.
  • 그 다음에는 notion.pages.create(parent={"database_id": ...})를 이용해 Row를 자동으로 추가/업데이트하면서, Notion을 사실상 “간단한 클라우드 DB”처럼 사용할 수 있습니다.

댓글 남기기