はじめに
hkob の雑記録の第248回目は、Notion API の Create a database の payload の変更対応について解説します。
Create a database
昨日依頼して修正してもらった Create a database のリファレンスページはこちらになります。
データベース自体は単なるコンテナになってしまったのでプロパティを持ちません。ただ、データソースは必ず一つは存在する必要があるので、最初のデータソースのプロパティだけは initial_data_source の下にこれまでの properties を設定できるようになっています。このため、PropertyCache の base_type に data_source
も設定できるようにしました。この base_type の判定のために、以下の判定メソッドを用意しました。
# @return [TrueClass, FalseClass] true if database type def database? @base_type == "database" end # @return [TrueClass, FalseClass] true if data_source type def data_source? @base_type == "data_source" end # @return [TrueClass, FalseClass] true if database or data_source type def database_or_data_source? %w[database data_source].include? @base_type end # @return [TrueClass, FalseClass] true if page type def page? @base_type == "page" end
これまで Create a database では property_schema を JSON の properties キーの下に設定して API を呼び出ししていました。この仕様は Create a data source では同じ設定となっています。一方で、上のリファレンスに書かれているように、Create a database ではこの property_schema を initial_data_source キーの下の properties に入れなくてはなりません。そこで、これまでの properties ハッシュを schema として一時保存し、database? の時だけ initial_data_source の下に記載するようにしました。
# @return [Hash] created property schema json def property_schema_json schema = @properties.each_with_object({}) do |(_, property), ans| if property.will_update ans["properties"] ||= {} ans["properties"].merge! property.property_schema_json end end database? ? {"initial_data_source" => schema} : schema end # @return [Hash] created update property schema json def update_property_schema_json schema = @properties.each_with_object({}) do |(_, property), ans| if property.will_update ans["properties"] ||= {} ans["properties"].merge! property.update_property_schema_json end end database? ? {"initial_data_source" => schema} : schema end
これに合わせて、それぞれの property のクラスにも database? と data_source? を用意しました。また、それぞれで対応する機能が異なるので動作テストをしています。また、実装側でも異なる型のメソッドが呼ばれた時に例外が発生するように assert が用意されていましたが、ここも data_source? の判定を追加しています。
# @param [Symbol, nil] method def assert_database_property(method) raise StandardError, "#{method} can execute only Database property." unless database? end # @param [Symbol, nil] method def assert_database_or_data_source_property(method) raise StandardError, "#{method} can execute only Database property." if page? end ## DataSource property only methods def assert_data_source_property(method) raise StandardError, "#{method} can execute only DataSource property." unless data_source? end
生成された databases の dry_run 結果はこのような感じになります。
curl -X POST 'https://api.notion.com/v1/databases/' \ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \ -H 'Content-Type: application/json' \ -H 'Notion-Version: 2025-09-03' \ --data '{ "parent": { "type": "page_id", "page_id": "c01166c613ae45cbb96818b4ef2f5a77" }, "icon": { "type": "emoji", "emoji": "🎉" }, "title":[{"type":"text","text":{"content":"New database title","link":null},"plain_text":"New database title","href":null}], "initial_data_source":{"properties":{"Checkbox":{"checkbox":{}},"CreatedBy":{"created_by":{}},"CreatedTime":{"created_time":{}},"Date":{"date":{}},"Email":{"email":{}},"Files":{"files":{}},"Formula":{"formula":{"expression":"now()"}},"LastEditedBy":{"last_edited_by":{}},"LastEditedTime":{"last_edited_time":{}},"MultiSelect":{"multi_select":{"options":[{"name":"MS1","color":"orange"},{"name":"MS2","color":"green"}]}},"Number":{"number":{"format":"yen"}},"People":{"people":{}},"PhoneNumber":{"phone_number":{}},"Relation":{"relation":{"data_source_id":"4f93db514e1d4015b07f876e34c3b0b1","type":"single_property","single_property":{}}},"Rollup":{"rollup":{"function":"sum","relation_property_name":"Relation","rollup_property_name":"NumberTitle"}},"RichText":{"rich_text":{}},"Select":{"select":{"options":[{"name":"S1","color":"yellow"},{"name":"S2","color":"default"}]}},"Title":{"title":{}},"Url":{"url":{}}}}}'
生成されたページは以下のようになりました。データベースにアイコンをつけても、データソースにはそれが影響しないようで、データソースのアイコンは空のままでした。これは最初のデータソースに付けて欲しいなと思います。
参考までに Create a data source の dry_run はこのような形になり、properties が直下に入っています。
curl -X POST 'https://api.notion.com/v1/data_sources/' \\ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \\ -H 'Content-Type: application/json' \\ -H 'accept: application/json' \\ -H 'Notion-Version: 2025-09-03' \\ --data '{ "parent": { "type": "database_id", "database_id": "2650ce2a6520808fbea9f247043f7f37" }, "icon": { "type": "emoji", "emoji": "🎉" }, "title":[{"type":"text","text":{"content":"New data source title","link":null},"plain_text":"New data source title","href":null}], "properties":{"Checkbox":{"checkbox":{}},"CreatedBy":{"created_by":{}},"CreatedTime":{"created_time":{}},"Date":{"date":{}},"Email":{"email":{}},"Files":{"files":{}},"Formula":{"formula":{"expression":"now()"}},"LastEditedBy":{"last_edited_by":{}},"LastEditedTime":{"last_edited_time":{}},"MultiSelect":{"multi_select":{"options":[{"name":"MS1","color":"orange"},{"name":"MS2","color":"green"}]}},"Number":{"number":{"format":"yen"}},"People":{"people":{}},"PhoneNumber":{"phone_number":{}},"Relation":{"relation":{"data_source_id":"2650ce2a6520809d991c000bf9cc5f17","type":"single_property","single_property":{}}},"Rollup":{"rollup":{"function":"sum","relation_property_name":"Relation","rollup_property_name":"NumberTitle"}},"RichText":{"rich_text":{}},"Select":{"select":{"options":[{"name":"S1","color":"yellow"},{"name":"S2","color":"default"}]}},"Title":{"title":{}},"Url":{"url":{}}}}'
おわりに
Create まで完了しました。もう少しで完了しそうです。