Notion APIで大量のページをリレーション付きで一括投稿する

Notion APIで大量のページをリレーション付きで一括投稿する

最新の更新日
Mar 6, 2025 1:30 PM
記事作成日
Sep 11, 2024 11:28 AM
Category
Notion
Tag Library
🐍Python📲API📚Notion
Target Keywords

vol.

Podcast

Super.soによるNotionサイト構築をご支援させていただく際、「リレーション付きの大量ページでも問題なくNotionが動作するか」が懸念事項としてあがりました。

NotionをWebサイトとして公開する方法 : SuperとWraptas(Anotion)

そこで、Notionのパフォーマンステストのため、約20,000件のページをリレーション付きの状態で入稿し、問題なく動作するかどうかの検証・テストを実施。結果としては問題なく動作することが確認できました。

Notionデータベースの速度・パフォーマンステスト:リレーションつき2万件のアイテム

本記事では、上記パフォーマンステストを実施した際、Notion API経由で大量ページをリレーション付きで投稿しましたので、その方法について詳細をご共有します。

目次:

  • Notion APIで特定のデータベースにページを一括投稿(リレーション付き)
  • Notion APIでは複数のページを一括アップロード(POST)することは許可されていない
  • リレーション付きでページ作成する場合のプログラム流れ
  • 0. notion-sdk-pyを使うための設定・準備
  • 1. あらかじめ関連するデータベースIDを取得しておく
  • 2. リレーション先アイテムのIDを取得
  • まずは子DB自体のIDを取得
  • 子DBのIDにもとづき、子DB内のページ情報をすべて取得
  • マルチセレクト項目の定義。指定したカラーでリストを作成
  • 3. 新規ページのプロパティを定義(リレーション先IDや他カラムの情報を追加)
  • プロパティの各項目について解説
  • 4.特定したデータベースへ新規ページを作成(プログラム実行)
  • ソースコード全体
  • 実行用ファイル
  • 関数ファイル(使用しなかった関数も含みます)
  • マルチセレクト定義および関数ファイル
  • 新規ページPOST用プロパティ

Notion APIで特定のデータベースにページを一括投稿(リレーション付き)

image

どのようにして20,000件ものページをデータベースに一括投稿したか、について方法をご共有いたします。

Notion APIを利用し、Pythonで容易にAPIを扱えるようにしてくれる公式のSDknotion-sdk-pynotion-sdk-py にてサンプルデータを大量入稿させました。

notion-sdk-py

notion-sdk-py is a simple and easy to use client library for the official Notion API.

notion-sdk-pyの利用にあたって、 【保存版】Python Notion 操作 (notion-sdk-py編) #GitHub - Qiita の記事がよくまとまっており、大変助けてもらいました🙏

Notion APIを用いると、通常のNotion操作では難しい大量のデータに対する操作、編集、整形が可能となります。

たとえば、NotionデータベースAPI操作: 主キー(タイトル列)を変更・入れ替えてデータベースを複製する の記事では通常Notionの仕様上不可となっている主キーの入れ替えをNotion APIからの操作によって実現しています。

また、追加とは反対にデータベース内のページを一括削除させることもできます。 Notionデータベースのレコード行を一括削除する(API, Python)

Notion APIでは複数のページを一括アップロード(POST)することは許可されていない

Notion APIでは複数のページを一括アップロード(POST)することはできません。

According to Notion support this is not possible. The feature has been requested but is not available on Oct. 20th 2022.

python - Updating multiple entries in a notion database with API - Stack Overflow

したがって厳密には一括投稿ではありませんが、プログラム実施単位でみると一括、という形となります。

そのため、for, while文などの繰り返し制御によってAPIによる1レコード投稿を繰り返して実施していくこととなります。

プログラム内では1POSTにつき3秒のストップをかけながら実施しているため、1ページ追加につきおよそ3秒+αかかります。

APIを利用する場合、インテグレーションを作成したうえ、該当ページおよびデータベースに対してAPI許可を与える必要があります。

参考: Notion APIの制限・注意点(メモ)

リレーション付きでページ作成する場合のプログラム流れ

リレーション付きでページを追加する場合、以下のような流れが必要となります。

  1. 新規ページを追加する先のデータベースを特定(データベースIDを取得)
  2. 新規ページに紐づける、リレーション先アイテムのIDを取得
  3. 新規ページのプロパティを定義(リレーション先IDや他カラムの情報を追加)
  4. 特定したデータベースへ新規ページを作成

0. notion-sdk-pyを使うための設定・準備

まずはライブラリを追加します。

# Ryeの場合
$ rye add notion-client

# pipの場合
$ pip install notion-client

Notionクライアントを作成します。

import os
from notion_client import Client

client = Client(auth=os.environ["NOTION_TOKEN"])

1. あらかじめ関連するデータベースIDを取得しておく

データベースIDは一度作成されてしまえば固定であり、毎回取得しておく必要はないため、あらかじめ取得しておいて定数として定義しておきます。

2. リレーション先アイテムのIDを取得

元DBにアイテムをアップロードする際、リレーションとして紐づけるアイテムを特定したうえでアップロードする必要があります。

リレーション先アイテムとは、 Notionパフォーマンステスト でいうところの「リレーション先DB_A」と「リレーション先DB_B」(子DB)のなかのアイテムとなります。

まずは子DB自体のIDを取得

これら子DBのなかのアイテムのIDを一覧で取得するために、まずは子DB自体のIDを取得します。

# Retrieve child DBs
child_db_results = get_db_names_and_ids_from_query(client, "リレーション先")

# Store
CHILD_DB_A_ID = db_results[0]["db_id"]
CHILD_DG_B_ID = db_results[1]["db_id"]

子DBのIDにもとづき、子DB内のページ情報をすべて取得

子DBのIDを取得できたら、IDをもとにDB内のページ情報をすべて取得します。

取得したページ情報一覧から、ページのIDのみをそれぞれ抜き出して辞書inリストの形で保持します。

マルチセレクト項目の定義。指定したカラーでリストを作成

マルチセレクトにどのような内容を定義すればよいのか?は Page properties: Multi-Select に記載があります。

ほか参考: Notion APIからDBアイテムを追加するときのプロパティごとの書き方 | ブログ | 静岡県のホームページ制作 | 6666666 セブンシックス

今回はランダムで6つの項目から選択されるようにしたいため、まずは各セレクト項目ごとに定義します。

下記のように各セレクト項目の定義を行うに際して、別途セレクト項目ごとのIDを取得しておく必要があります。(下記各セレクト項目の’id’内容はダミー)

セレクト項目のパターンを生成するための関数を以下のように作成しました。

関数を利用して適当なパターンでカラーリストを作成します。

3. 新規ページのプロパティを定義(リレーション先IDや他カラムの情報を追加)

新規追加するページのプロパティを定義します。どのようなプロパティを追加すればよいか?については Page properties に記述があります。

Page properties

👍 Page properties are most useful when interacting with a page that is an entry in a database, represented as a row in the Notion UI. If a page is not part of a database, then its only available property is its title . A page object is made up of page properties that contain data about the page. Wh...

Page properties

リッチテキストのプロパティについてだけは、 Rich text のページに詳細情報がありました。

下記page_propertyのうち、’リレーション先DB’のIDはリレーション先DBのIDではなく、元DBにおけるリレーションカラムのID(カラムID)です。

プロパティの各項目について解説

プロパティの各項目は、以下の3つの要素を基本として成り立ちます。各タイプによって追加可能な要素が異なりますが、以下の3つが基本的な共通要素だと認識してよいでしょう。

ただし、実際はほとんどが省略可能です。3番目のcontent-listのみ定義してもOKです。

  1. id: 本カラムのIDを表す (任意。IDを付与せずともカラム名がユニークならIDは省略可)
  2. type: カラムの種類を表す。title, rich_text, relation, multiselect など (省略可)
  3. content-list: カラムの主たる内容。2のカラム種類をキー名とし、内容をリストとして含める。
    1. 例: 'relation': [{"id": child_id} for child_id in child_page_A_ids]

上記の各項目は、カラム名によって囲まれることで1つのカラムの内容を表します。

たとえば、「テキストフィールド」というカラム名のリッチテキストフィールドの場合は下記。

極めてシンプルにするなら下記。

'テキストフィールド': {
            'rich_text': [{
                "text": {
                    "content": post_text,
                }
            }],
        }

4.特定したデータベースへ新規ページを作成(プログラム実行)

作成してきた内容をもとに、元DBへ新規ページを作成します。

途中、マルチセレクトを4パターンでランダム選択し、また新規ページに紐づけるリレーション先アイテムもランダムに1〜5個が選択されたうえで投稿されるようにしてあります。

以上で、Notion API経由でリレーション付きで一括ページ投稿をすることが可能です!

ソースコード全体

以下にソースコード全体を示します。

実行用ファイル

関数ファイル(使用しなかった関数も含みます)

マルチセレクト定義および関数ファイル

新規ページPOST用プロパティ

Category: 📚Notion

Tags: 🐍Python

この記事の気になる箇所を読み返す:

  • Notion APIで特定のデータベースにページを一括投稿(リレーション付き)
  • Notion APIでは複数のページを一括アップロード(POST)することは許可されていない
  • リレーション付きでページ作成する場合のプログラム流れ
  • 0. notion-sdk-pyを使うための設定・準備
  • 1. あらかじめ関連するデータベースIDを取得しておく
  • 2. リレーション先アイテムのIDを取得
  • まずは子DB自体のIDを取得
  • 子DBのIDにもとづき、子DB内のページ情報をすべて取得
  • マルチセレクト項目の定義。指定したカラーでリストを作成
  • 3. 新規ページのプロパティを定義(リレーション先IDや他カラムの情報を追加)
  • プロパティの各項目について解説
  • 4.特定したデータベースへ新規ページを作成(プログラム実行)
  • ソースコード全体
  • 実行用ファイル
  • 関数ファイル(使用しなかった関数も含みます)
  • マルチセレクト定義および関数ファイル
  • 新規ページPOST用プロパティ

📜
Scripts