Notionのテーブルビューからデータを取得する【Python, Notion API】

Notionのテーブルビューからデータを取得したい機会があったので忘れないようにメモしておきます。

## :book: 参考にしたページ

:bulb: Notion APIの使い方について
ほぼこちらのサイトを見ながら作業しました。
とてもわかりやすいので先に見ることをおすすめします。

https://notion-lab.jp/2023-09-30-python-notion-api/#Python%20%E5%AE%9F%E8%A1%8C%E7%92%B0%E5%A2%83%E3%81%AE%E6%BA%96%E5%82%99

:bulb: トークンの取得などについて

https://programming-zero.net/notion-api-setting/

:bulb: 取得する際に適用するフィルタについて

https://developers.notion.com/reference/post-database-query-filter

## 必要なもの

1. 取得する対象となるテーブルビュー（自分で所有しているもの）
2. データベースID
3. APIキー
4. Python3とrequestsモジュール

## 0. データベース（テーブルビュー）の作成

まずはテスト用に次のようなデータベース（テーブルビュー）を作成しました。

![notion_db_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/785720/59b401ee-ca09-e1a5-b15d-740a5395b235.jpeg)


## 1. データベースIDの取得

Notionのテーブルからデータを取得するにはデータベースIDを指定する必要があります。

ビューの名前（ここでは「サンプル」という名前にしました）のブロックをクリックして、対象のビューのリンクを取得します。

![notion_db_03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/785720/4141676d-c282-02f1-deac-7bf8a22b0739.jpeg)


ここで取得したデータベースのURLは

`https://wwww.notion.so/<データベースID>?v=xxxxxxx`の形式になっています。

今回作成したデータベースのURLは

```
https://www.notion.so/xxxxxxxxxxxxx7266?v=123456789abcefghijk
```

のような文字列だったので、この場合は`xxxxxxxxxxxxx7266`がデータベースIDです。

## 2. API KEYの取得

次のページで「新しいインテグレーション」を追加してAPIキーを取得します。
https://www.notion.so/my-integrations [^1]

[^1]: ページ右上の
`・・・` > `コネクト` > `接続先` > `コネクトを管理`
に進み、表示された設定画面から
`自分のコネクト` > `インテグレーションを作成または管理する`
をクリックすれば上記リンクにたどり着きます。

ここでは名前を「Notion-APIテスト」にしました。

![notion_db_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/785720/3c71a387-11ca-cfe2-63ab-42e3cd0a98e3.jpeg)


「送信」を押すとNotion APIのキー（トークン）が表示されます。

![スクリーンショット 2024-04-29 150445.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/785720/3fdd283f-89f0-043d-152b-ce34170f9566.jpeg)

### インテグレーションをワークスペースに連携

対象のワークスペースに戻り、メニューの「コネクト」セクションから「接続先」> 「Notion-APIテスト」をクリックします。確認メッセージが表示されたら、内容を確認して「はい」をクリックします。

![スクリーンショット 2024-04-29 150933.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/785720/419ee073-ef7a-c9e5-84e3-a49422d4343a.jpeg)


すると次の画像のように「コネクト」の欄に追加したインテグレーションが表示されます。

![スクリーンショット 2024-04-29 151300.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/785720/b24a3cd6-5412-ed1d-0f87-d8dffe5700c3.jpeg)


## 3. データの取得

データベースの取得にはPython3と`requests`モジュールを使用します。(Python3の導入方法については他記事を参照してください)

`requests`が入っていない場合は`pip install requests`をして入れておきます。

```python
# notion_test.py
import requests
from pprint import pprint

NOTION_API_KEY = "secrets_xxxxxxxxx"  # API KEYをここに設定
DATABASE_ID = "xxxxxxxxxxxxxx"  # データベースIDをここに設定

url = f"https://api.notion.com/v1/databases/{DATABASE_ID}/query"

headers = {
    "Notion-Version": "2022-06-28",
    'Authorization': 'Bearer ' + NOTION_API_KEY,
    'Content-Type': 'application/json',
}

response = requests.post(url, headers=headers)
pprint(response.json())
```

実行すると次のように全データが含まれた結果が得られます。

```bash
$ python notion_test.py
{'has_more': False,
 'next_cursor': None,
 'object': 'list',
 'page_or_database': {},
 'request_id': 'xxxxxxxx',
 'results': [{'archived': False,
              'cover': None,
              'created_by': {'id': 'xxxxxxxx',
                             'object': 'user'},
              'created_time': '2024-04-29T05:35:00.000Z',
              'icon': None,
              'id': 'xxxxxxxx',
              'in_trash': False,
              'last_edited_by': {'id': 'xxxxxxxx',
                                 'object': 'user'},
              'last_edited_time': '2024-04-29T05:37:00.000Z',
              'object': 'page',
              'parent': {'database_id': 'xxxxxxxx',
                         'type': 'database_id'},
              'properties': {'セレクト': {'id': 'yyyzzzz',
                                      'select': {'color': 'orange',
                                                 'id': 'xxxxxxxx',
                                                 'name': 'セレクトボックスA'},
                                      'type': 'select'},
                             'タグ': {'id': 'yyyzzzz',
                                    'multi_select': [{'color': 'pink',
                                                      'id': 'xxxxxxxx',
                                                      'name': 'タグA'},
                                                     {'color': 'purple',
                                                      'id': 'xxxxxxxx',
                                                      'name': 'タグ１'}],
                                    'type': 'multi_select'},
                             '名前': {'id': 'title',
                                    'title': [{'annotations': {'bold': False,
                                                               'code': False,
                                                               'color': 'default',
                                                               'italic': False,
                                                               'strikethrough': False,
                                                               'underline': False},
                                               'href': None,
                                               'plain_text': '名前A',
                                               'text': {'content': '名前A',
                                                        'link': None},
                                               'type': 'text'}],
                                    'type': 'title'}},
              'public_url': None,
              'url': 'https://www.notion.so/A-xxxxxxx'},
             {'archived': False,
              'cover': None,
              'created_by': {'id': 'xxxxxxxx',
                             'object': 'user'},
              'created_time': '2024-04-29T05:35:00.000Z',
              'icon': None,
              'id': 'xxxxxxxx',
              'in_trash': False,
              'last_edited_by': {'id': 'xxxxxxxx',
                                 'object': 'user'},
              'last_edited_time': '2024-04-29T05:37:00.000Z',
              'object': 'page',
              'parent': {'database_id': 'xxxxxxxx',
                         'type': 'database_id'},
              'properties': {'セレクト': {'id': 'yyyzzzz',
                                      'select': {'color': 'yellow',
                                                 'id': 'xxxxxxxx',
                                                 'name': 'セレクトボックスB'},
                                      'type': 'select'},
                             'タグ': {'id': 'yyyzzzz',
                                    'multi_select': [{'color': 'orange',
                                                      'id': 'xxxxxxxx',
                                                      'name': 'タグB'}],
                                    'type': 'multi_select'},
                             '名前': {'id': 'title',
                                    'title': [{'annotations': {'bold': False,
                                                               'code': False,
                                                               'color': 'default',
                                                               'italic': False,
                                                               'strikethrough': False,
                                                               'underline': False},
                                               'href': None,
                                               'plain_text': '名前B',
                                               'text': {'content': '名前B',
                                                        'link': None},
                                               'type': 'text'}],
                                    'type': 'title'}},
              'public_url': None,
              'url': 'https://www.notion.so/B-xxxxxxx'},
             {'archived': False,
              'cover': None,
              'created_by': {'id': 'xxxxxxxx',
                             'object': 'user'},
              'created_time': '2024-04-29T05:35:00.000Z',
              'icon': None,
              'id': 'xxxxxxxx',
              'in_trash': False,
              'last_edited_by': {'id': 'xxxxxxxx',
                                 'object': 'user'},
              'last_edited_time': '2024-04-29T05:35:00.000Z',
              'object': 'page',
              'parent': {'database_id': 'xxxxxxxx',
                         'type': 'database_id'},
              'properties': {'セレクト': {'id': 'yyyzzzz',
                                      'select': None,
                                      'type': 'select'},
                             'タグ': {'id': 'yyyzzzz',
                                    'multi_select': [],
                                    'type': 'multi_select'},
                             '名前': {'id': 'title',
                                    'title': [],
                                    'type': 'title'}},
              'public_url': None,
              'url': 'https://www.notion.so/xxxxxx'}],
 'type': 'page_or_database'}
```

例えば、「名前」が「名前A」になっているデータを取得する場合

```python
json_data =  {
    'filter': {
    'property': '名前',  # ここに項目名称をいれる
        'title': {  # セレクトなら"select", マルチセレクトなら"multi_select"などに
            'equals': '名前A'   
        }
    }
}

response = requests.post(url, headers=headers, json=json_data)
```

のようにフィルタを設定すると、

```bash
$ python notion_test.py
{'has_more': False,
 'next_cursor': None,
 'object': 'list',
 'page_or_database': {},
 'request_id': 'xxxxxxxxxxxx',
 'results': [{...（略）...,
              'properties': {'セレクト': {'id': 'xxxxxxxxxxxx',
                                      'select': {'color': 'orange',
                                                 'id': 'xxxxxxxxxxxx',
                                                 'name': 'セレクトボックスA'},
                                      'type': 'select'},
                             'タグ': {'id': 'ySG%7B',
                                    'multi_select': [{'color': 'pink',
                                                      'id': 'xxxxxxxxxxxx',
                                                      'name': 'タグA'},
                                                     {'color': 'purple',
                                                      'id': 'xxxxxxxxxxxx',
                                                      'name': 'タグ１'}],
                                    'type': 'multi_select'},
                             '名前': {'id': 'title',
                                    'title': [{'annotations': {'bold': False,
                                                               'code': False,
                                                               'color': 'default',
                                                               'italic': False,
                                                               'strikethrough': False,
                                                               'underline': False},
                                               'href': None,
                                               'plain_text': '名前A',
                                               'text': {'content': '名前A',
                                                        'link': None},
                                               'type': 'text'}],
                                    'type': 'title'}},
              'public_url': None,
              'url': 'https://www.notion.so/A-xxxxxxxxxxxxxx'}],
 'type': 'page_or_database'}
```

といった感じで指定したデータだけ取り出すことができます。

フィルタのかけ方について詳しくは公式ドキュメントを参照するのが良いと思います。

https://developers.notion.com/reference/post-database-query-filter#the-filter-object