Python으로 Notion Database에 JSON 데이터 업로드하기

Python으로 Notion Database에 데이터 업로드하기

이전 글에서, Selenium과 BeautifulSoup을 사용해서 네이버 클라우드 플랫폼 가이드 정보를 추출해서, JSON 포맷으로 저장했다. 이번 글에서는, 저장된 정보를 Notion Database에 추가해 보겠다.

사실 과정 자체는 은근히 간단한데, 노션 API 자체의 한계로 노가다가 필요하다.

API 키 발급받기 & 데이터베이스 ID 확인하기

Notion 내 API 통합 페이지에서, API를 하나 발급받는다.

그리고 '기능' 탭에 들어가서, 권한을 확인해 준다. 콘텐츠 읽기, 업데이트, 입력 등의 권한이 체크돼 있는 지 확인해준다.

그리고 연동하고자 하는 데이터베이스의 ID를 확인한다. 이는 데이터베이스의 URL에서 확인할 수 있다.

저기에 있는 링크 복사를 누르면 아래와 같이 URL이 나온다.

https://www.notion.so/nx006/<db_id>?v=dfks...

위에서 <db_id> 부분이 데이터베이스의 ID이다. 이 복사한다.

그리고 노션 페이지에서, API 키를 등록을 해준다. DB 페이지로 들어가서

메뉴에서 연결 추가를 누르고, 내가 설정한 API를 선택하면 된다. 나는 이미 연결을 추가해놓아서, 저렇게 사진과 같이 뜬다. 참고로 API 키 설정에 읽기, 쓰기 설정이 모두 허용돼 있는지 다시 확인해 보자.

Database 세팅하기

의도된 건지는 모르겠는데, 노션 DB에 데이터를 연동시키기 위해서는 데이터와 DB의 구조, 그리고 내부 요소가 "정확히" 일치해야 한다.

여기서 불만이었던 점이, DB의 컬럼(열) 구조를 미리 만들어놓는 건 좋다. 그런데 다중 선택 유형에서, 하나하나의 선택지는 미리 만들어야 한다. POST 시에 새로운 원소 만나면 새로 추가하는 기능 따윈 없다.

만약에 기존에 없는 새로운 선택지가 POST 요청으로 들어오면 에러를 반환한다고 한다. 그래서 일종의 노가다 작업을 해야 할 시간이다!

이전에 JSON 파일의 형태를 살펴보자.

[
    {
        "name": "Cloud Functions로 액션 실행",
        "프로젝트 구성시 필요 경험치": "초급",
        "기술 항목": [
            "Cloud Functions"
        ],
        "url": "https://www.ncloud.com/guideCenter/guide/4"
    },
    {
        "name": "Linux 서버 생성",
        "프로젝트 구성시 필요 경험치": "초급",
        "기술 항목": [
            "Server",
            "ACG",
            "PuTTY"
        ],
        "url": "https://www.ncloud.com/guideCenter/guide/1"
    },
    {
        "name": "Windows 서버 생성",
        "프로젝트 구성시 필요 경험치": "초급",
        "기술 항목": [
            "Server",
            "ACG"
        ],
        "url": "https://www.ncloud.com/guideCenter/guide/3"
    }
]

컬럼은 4개를 추가하면 되겠다. 이름(Name), Experience Level(프로젝트 구성시 필요 경험치), Tech Items(기술 항목), URL(url)이다.

  • 이름: 제목(title)
  • Experience Level: 선택(select)
    • 초급
    • 중급
    • 보통
  • Tech Items: 다중 선택(multi_select)
    • Server
    • ACG
    • PuTTY
    • ...
  • URL: URL

Experience Level에는 초급, 중급, 보통을 추가한다. 그리고 Tech Items에는 JSON 파일을 돌며 모든 기술 항목을 하나하나 추가한다.



54개 원소 정도만 깔끔하게 입력해 주면 된다.

코드 작성

.env 파일 작성

우선 .env 파일에 API 키와 DB ID를 입력한다.

NOTION_API_KEY=<api_key>
NOTION_DB_ID=<db_id>

api_key와 db_id는 위에서 확인한 값을 입력하면 된다.

코드 작성

from notion_client import Client


def upload_to_notion(guides_info, notion_api, notion_db_id):
    # notion api
    notion = Client(auth=notion_api)
    database_id = notion_db_id

    for guide in guides_info:
        page = notion.pages.create(
            parent={"database_id": database_id},
            properties={
                "Name": {"title": [{"text": {"content": guide["name"]}}]},
                "Experience Level": {"select": {"name": guide["프로젝트 구성시 필요 경험치"]}},
                "Tech Items": {
                    "multi_select": [{"name": item} for item in guide["기술 항목"]]
                },
                "URL": {"url": guide["url"]},
            },
        )

위 함수는 JSON 형태의 guides_info와 API 키, DB ID를 인자로 받아서, 노션 DB에 업로드하는 함수이다. 이를 위해서는 notion_client 라이브러리를 설치해야 한다.

$ pip install notion-client

간단하게 설명하자면, guides_info의 각 가이드를 순회하면서 create 요청을 DB에 날린다. 이때 properties에 DB 컬럼 이름과 유형, 값을 넣어준다.

이를테면 Name은 유형이 title, Experience Level은 유형이 select, Tech Items는 유형이 multi_select이다.

main 함수는 아래와 같이 작성했다.

def main():
    # read json file
    with open("assets/guides_info.json", "r") as f:
        guides_info = json.load(f)

    # notion api
    notion_api = os.environ.get("NOTION_TOKEN")
    notion_db_id = os.environ.get("NOTION_DATABASE_ID")

    print(f"notion_api: {notion_api}")
    print(f"notion_db_id: {notion_db_id}")

    # 10개씩 나누어서 노션에 업로드
    for i in range(0, len(guides_info), 10):
        print(f"Uploading {i} to {i+10} guides to Notion")
        upload_to_notion(guides_info[i : i + 10], notion_api, notion_db_id)


if __name__ == "__main__":
    load_dotenv()
    main()

이제 실행해 보자. 이때 참고로 10개씩 나누어서 노션에 업로드하는 함수를 호출하고 있는데, 그 이유는 한 번에 너무 오래 Notion Client를 실행할 경우, Timeout Error가 발생했기 때문이다. 그래서 적당히 10개씩 나누어서 실행하도록 했다.

 

아래 실행 영상인데, 약 3배속 했다. 실제로는 1~2분 정도 걸려서, Timeout Error 발생하지 않게 적당히 끊어주는 게 좋다 (처음에 올릴 때 내가 계속 타임 아웃 에러 떠서 뭔가 했었다).

먼 길 돌아오긴 했는데, 이로써 43개의 가이드의 기술 항목과 난이도 등을 한눈에 볼 수 있게 됐다. 자동화되었으니, 혹여 나중에 쉬운 시작 가이드가 더 늘어나도, 쉽게 업데이트할 수 있을 것이다(페이지 구조가 변하지 않는 한).

Notion DB는 필터링이 가능하다. 사실 내가 원하던 기능이 바로 이거였는데, Naver Cloud Platform에서는 Essential Guide라고 해서 동영상으로 된 강의를 제공을 한다. 총 10개의 동영상 강의가 제공되는데, 이 10개 각각의 내용에 연관된 쉬운 시작 가이드 문서를 필터링해서 링크하고 싶었다.

이런 식으로, 예를 들어 Server와 Auto Scailing을 선택하면, 이 속성이 포함된 가이드 문서들이 필터링되는 것을 기대했고, 완벽하게 작동된다! 끝이다!