"notion-database" Python 라이브러리로 Notion Database 다뤄보기!

NewNewDaddy·2025년 3월 10일
1

PYTHON

목록 보기
10/10
post-thumbnail

🔹 0. INTRO

  • 사람들이 많이 사용하는 생산성 툴 중에 가장 대표적인 것인 노션이 아닐까 생각합니다. 글을 정리하고 아카이빙하고, 진행 상황을 체크하는 등 많은 업무를 할 때 노션 만큼 깔끔하고 자유도 높은 플랫폼이 잘 없는 것 같습니다.
  • 파이썬을 활용하는 사람으로써, 주로 사용하는 SaaS 플랫폼에 대해 어떻게 이 기능들을 파이썬으로 다룰 수 있을까 항상 생각을 해보곤 합니다. 노션 역시도 개발자들이 사용할 수 있도록 API를 제공하고 있습니다. 하지만 활용하기 위해서는 파라미터를 여러 중첩 JSON 구문에 포맷에 맞게 구성하여 request를 날려줘야 하기 때문에 복잡하고 직관성이 떨어졌습니다. 노션에서 공식적으로 개발되는 파이썬 관련 라이브러리는 또 없는 상황이라 다른 개발자들이 따로 만든 노션 관련 라이브러리들을 활용해야 했습니다.
  • 이번 글에서는 노션의 데이터베이스를 다룰 수 있도록 개발된 notion-database 라는 라이브러리에 대한 사용기 및 활용법에 대해 정리해볼까 합니다.

🔹 1. Notion API 발급 & 연동

▪ 1) Notion API 발급

  • notion API integration 사이트에 들어가 새로운 API를 생성하고 토큰을 발급받습니다.
  • 아래와 같이 새 API 통합을 클릭한 후 필요 내용들을 채우고 저장을 눌러줍니다.
  • 그러면 프라이빗 API 통합 시크릿 API 키를 발급 받을 수 있습니다.

▪ 2) Notion 페이지 연동

  • 파이썬으로 작업할 데이터베이스가 위치한 페이지에 가서 ...연결위에서 생성한 API 이름 선택 차례대로 설정하면 해당 페이지와 노션 API 연동이 활성화됩니다.

🔹 2. notion-database 라이브러리 활용

▪ 0) 공식 문서 & 설치

설치

pip install notion-database pendulum

▪ 1) 데이터베이스 리스트업

  • 사용중인 노션 계정에 있는 데이터베이스를 오름차순/내림차순으로 정렬하여 정보들을 출력합니다.
from notion_database.search import Search
from notion_database.const.query import Direction, Timestamp

NOTION_API_KEY = ""

def list_databases(notion_api_key):
    S = Search(integrations_token=notion_api_key)
    S.search_database(query="",
                      sort={"direction": Direction.descending,
                            "timestamp": Timestamp.last_edited_time},
                      root_only=False)
    return S.result

db = list_databases(NOTION_API_KEY)

for i in db:
    print(i['id'], print(i['title'][0]['plain_text']))

▪ 2) 데이터베이스 생성

  • 여러가지 속성들을 가진 새로운 데이터베이스를 생성하기 위해서는 아래 세 가지 정보가 필요합니다.
    1) NOTION API KEY
    2) 데이터베이스가 생성될 페이지의 ID
    3) 데이터베이스가 가질 속성(열)들

  • 페이지 ID는 해당 페이지의 URL에서 확인할 수 있습니다.

  • 아래 예시 코드에서는 이름, 선택지, 다중 옵션, 번호, 실행 여부, 실행 날짜 이렇게 다섯가지 속성을 가진 데이터베이스를 생성합니다.

  • '속성의 종류' : '속성의 이름' 이런식의 쌍으로 딕셔너리(dictionary)를 작성하게 되면 함수 내부에서 속성의 종류를 매칭시켜 그에 맞는 속성을 생성하도록 메소드를 호출합니다.

from notion_database.database import Database
from notion_database.properties import Properties
import pendulum

NOTION_API_KEY = ""
PAGE_ID = "1990f478367a80e4a14fc0cba53dfb05"
# "속성의 종류 : 속성의 이름" 이런식으로 작성
PROPERTY_DICT = dict(
    title = "이름",
    select = "선택지",
    multi_select = '다중 옵션',
    number = '번호',
    checkbox = '실행 여부',
    date = '실행 날짜'
)
DATABASE_NAME = 'VELOG NOTION DATABASE'
  
def create_database(notion_api_key, parent_page_id, title, properties, is_inline=False):
    D = Database(integrations_token=notion_api_key)
    PROPERTY = Properties()
    for prop_type, prop_name in properties.items():
        if prop_type == 'title':
            PROPERTY.set_title(prop_name)
        elif prop_type == 'rich_text':
            PROPERTY.set_rich_text(prop_name)
        elif prop_type == 'number':
            PROPERTY.set_number(prop_name)
        elif prop_type == 'select':
            PROPERTY.set_select(prop_name)
        elif prop_type == 'multi_select':
            PROPERTY.set_multi_select(prop_name)
        elif prop_type == 'checkbox':
            PROPERTY.set_checkbox(prop_name)
        elif prop_type == 'url':
            PROPERTY.set_url(prop_name)
        elif prop_type == 'email':
            PROPERTY.set_email(prop_name)
        elif prop_type == 'phone_number':
            PROPERTY.set_phone_number(prop_name)
        elif prop_type == 'date':
            PROPERTY.set_date(prop_name)
        elif prop_type == 'files':
            PROPERTY.set_files(prop_name)

    D.create_database(page_id=parent_page_id, title=title, properties=PROPERTY, is_inline=is_inline)
    return D.result
  
new_db = create_database(NOTION_API_KEY, PAGE_ID, DATABASE_NAME, PROPERTY_DICT, is_inline=True)
  
print(new_db)
  • 실행이 완료되면 사용자가 정의한 속성과 제목으로 노션 데이터베이스가 생성됩니다.

▪ 3) 데이터베이스 정보 조회

  • 노션에 생성되어있는 데이터베이스의 정보를 조회하기 위한 함수입니다. 데이터베이스 ID, 속성, 생성 시각, 수정 시각, 위치한 페이지의 ID 등 데이터베이스 관련된 다양한 정보들을 볼 수 있습니다.
  • 정보 조회를 위해서는 해당 데이터베이스의 ID가 필요합니다. 데이터베이스 ID는 ...Default view 보기 링크 복사 하여 얻은 링크에서 확인할 수 있습니다.

from notion_database.database import Database
from pprint import pprint

def get_database_properties(notion_api_key, database_id):
    D = Database(integrations_token=notion_api_key)
    D.retrieve_database(database_id=database_id)
    return D.result

DATABASE_ID = '1b20f478367a8108b606dd3e1cc3b2c7'
res = get_database_properties(NOTION_API_KEY, DATABASE_ID)
  
pprint(res)

▪ 4) 데이터베이스 페이지(행) 생성

  • 위에서 생성한 데이터베이스의 속성에 맞게 데이터를 삽입하는 코드입니다.
  • 삽입될 데이터는 '속성의 이름' : '데이터' 형식으로 작성되어야 하며, 해당 속성에 넣을 데이터가 없다면 빈 값으로 작성해주면 됩니다.
from notion_database.page import Page
from datetime import datetime

properties = {
    '이름' : "VELOG",
    '선택지' : "호주",
    '다중 옵션' : ['멜버른', '시드니', '캠버라'],
    '번호' : 100,
    '실행 여부' : True,
    '실행 날짜' : datetime.now().strftime("%Y-%m-%d %H:%M:%S") + '+0900'
    }
DATABASE_ID = '1b20f478367a8108b606dd3e1cc3b2c7'

def create_database_page(notion_api_key, database_id, properties, child_properties=False):
    PROPERTY = Properties()
    
    res = get_database_properties(notion_api_key, database_id)
    
    for k, v in res['properties'].items():
        property_type = v['type']
        if k in properties:
            getattr(PROPERTY, f'set_{property_type}')(k, properties[k])
    
    P = Page(integrations_token=notion_api_key)
    P.create_page(database_id=database_id, properties=PROPERTY)
    return P.result

create_database_page(NOTION_API_KEY, DATABASE_ID, properties)
  • 실행해보면 사용자가 정의한 properties의 내용과 동일하게 Notion 데이터베이스에 행이 생성된 것을 확인할 수 있습니다.

▪ 5) 데이터베이스 페이지(행) 업데이트

  • 데이터베이스에 삽입된 데이터를 수정하는 코드입니다.
# 수정할 데이터베이스 페이지의 ID
PAGE_ID = ''

def update_database_properties(notion_api_key, page_id):
	P = Page(integrations_token=notion_api_key)
	"""
    속성별 업데이트 값 명시
    PROPERTY.[속성 메소드]('속성 이름', '업데이트 데이터') 포맷으로 작성합니다.
    아래 예시는 아래와 같이 업데이트 합니다
    	- 이름 -> Hyunsoo로 변경
        - 번호 -> 200으로 변경
    """
    PROPERTY.set_title("이름", "Hyunsoo")
    PROPERTY.set_number('번호;', 200)
    P.update_page(page_id=page_id, properties=PROPERTY)
    return P.result
    
update_database_properties(NOTION_API_KEY, PAGE_ID)

▪ 6) 데이터베이스 페이지 삭제(아카이브)

  • 데이터베이스에 저장된 특정 페이지(행)를 휴지통으로 이동시킵니다.
def archive_database_properties(notion_api_key, page_id):
    P = Page(integrations_token=notion_api_key)
    P.archive_page(page_id=page_id, archived=True)
    return P.result
    
archive_database_properties(NOTION_API_KEY, PAGE_ID)

▪ 7) 데이터베이스 페이지 목록 조회

  • 데이터베이스에 저장된 페이지들의 목록을 조회합니다.
def list_pages_in_database(notion_api_key, database_id):
    D = Database(integrations_token=notion_api_key)
    D.find_all_page(database_id=database_id)
    return D.result

list_pages_in_database(NOTION_API_KEY, DATABASE_ID)

▪ 8) 페이지 내부 Children Block 생성

  • 'Children Block'이란 노션 데이터베이스에 생성된 페이지 내에 입력될 내용을 뜻합니다.
  • 7번까지의 기능들은 데이터베이스에 특정 속성을 가진 페이지를 생성하는 것이었습니다. 'Children Block' 생성 기능은 해당 페이지 내에 더 자세한 데이터 입력이 필요한 경우 추가적으로 활용할 수 있습니다.
  • 아래 코드에서 알 수 있듯 페이지 내부에 구성될 내용들의 항목을 Children() 객체에 정의해주는 형식으로 정보를 만들어 전달해줄 수 있습니다.
    ` 객체에
# 1) children properties 설정
def set_children_properties():
    C = Children()
    """
    Docs 기준 코드 참조
    """
    # 단순 문단
    C.set_paragraph("set_paragraph")
    C.set_paragraph("set_paragraph", color=clr.BLUE)

    # 헤더
    C.set_heading_1("set_heading_1")
    C.set_heading_2("set_heading_2")
    C.set_heading_3("set_heading_3")
    C.set_heading_1("set_heading_1", color=clr.BLUE)
    C.set_heading_2("set_heading_2", color=clr.BLUE_BACKGROUND)
    C.set_heading_3("set_heading_3", color=clr.GREEN)

    # 콜아웃
    C.set_callout("set_callout")
    C.set_callout("set_callout",color=clr.RED_BACKGROUND)

    # 인용문
    C.set_quote("set_quote")
    C.set_quote("set_quote",color=clr.RED)

    # 글머리 기호 구문
    C.set_bulleted_list_item("set_bulleted_list_item")
    C.set_bulleted_list_item("set_bulleted_list_item", color=clr.BROWN)

    # 숫자 구문
    C.set_numbered_list_item("first set_numbered_list_item")
    C.set_numbered_list_item("second set_numbered_list_item", color=clr.BROWN)

    # to do list
    C.set_to_do("set_to_do", checked=True)
    C.set_to_do("set_to_do", checked=False, color=clr.RED)

    # 토글
    C.set_toggle("set_toggle", children_text="WOW!", color=clr.BLUE)

    # 코드 블럭
    C.set_code("set_code")
    C.set_code("const a = 1", lang="javascript")
    C.set_code("print(\"hello world!\")", lang='python')
    C.set_embed("https://linktr.ee/hyunsoo.it")
    C.set_external_image("https://github.githubassets.com/images/modules/logos_page/Octocat.png")
    C.set_external_video("http://download.blender.org/peach/trailer/trailer_480p.mov")
    C.set_external_file("https://github.com/microsoft/ML-For-Beginners/raw/main/pdf/readme.pdf")
    C.set_external_pdf("https://github.com/microsoft/ML-For-Beginners/blob/main/pdf/readme.pdf")
    C.set_bookmark("https://linktr.ee/hyunsoo.it")

    C.set_equation("e=mc^2")

    C.set_divider()
    C.set_table_of_contents()
    C.set_breadcrumb()
    
    return C
    
properties = {
    '이름' : "VELOG",
    '선택지' : "호주",
    '다중 옵션' : ['멜버른', '시드니', '캠버라'],
    '번호' : 100,
    '실행 여부' : True,
    '실행 날짜' : datetime.now().strftime("%Y-%m-%d %H:%M:%S") + '+0900'
    }
DATABASE_ID = '1b20f478367a8108b606dd3e1cc3b2c7'
C = set_children_properties()

# 4) 에서 생성한 함수 활용
create_database_page(
	notion_api_key = NOTION_API_KEY,
    database_id = DATABASE_ID, 
    properties = properties, 
    child_properties = C)

🔹 3. OUTRO

  • 노션은 직관적이고 세련된 UI뿐만 아니라 높은 자유도를 제공하기 때문에 업무에서 매우 유용하게 활용되는 도구입니다. 따라서 항상 파이썬을 활용하여 노션을 다루는 방법을 실습하고 정리해보고 싶었는데, 이번에 notion-database 라는 적절한 라이브러리를 찾아 이를 정리할 기회를 가지게 되었습니다.
  • 일반적으로 노션 페이지에서는 사용자가 직접 내용을 생성, 수정, 삭제하는 경우가 많지만, 특정 데이터를 아카이빙하거나, 파이프라인의 중간 과정에서 노션 데이터베이스와 연동하여 데이터를 기록해야 할 때 파이썬을 활용할 수 있다면 훨씬 더 편리할 것이라고 생각됩니다.
  • 실제로 제가 구독하는 미디움(Medium) 사이트에서는 매일 아침 약 15개의 추천 글 리스트를 메일로 보내주는데, 해당 데이터를 크롤링하여 노션 데이터베이스에 저장하는 작업 코드가 매일 자동으로 실행되고 있습니다. 그 코드를 구성할 때 위에 다룬 notion-database 라이브러리가 사용되었습니다.👍
profile
데이터 엔지니어의 작업공간 / #PYTHON #CLOUD #SPARK #AWS #GCP #NCLOUD

0개의 댓글