はじめに
hkob の雑記録の第210回目は、Concerts & Devices の曲目リストとなる SetList を追加します。
ER図
SetList は Concerts, Devices に接続します。逆に Performances から SetLists に接続されます。Year, Map はさまざまなものに接続されるので、プロパティだけの表示とします。逆にリレーションの線を繋いでいるものはプロパティ表記を省略します。

SetLists のエクスポート
SetLists は以下のプロパティをエクスポートすることにします。SetLists は Concerts および Devices の二つのデータベースのどちらかに接続します。本当は先に SetLists を作っておき、後から昨日作成した Performances に繋げるべきでした。話間違えて先に Performances を作ってしまったので、SetLists 側から接続することにします。昨日と同様に Name は後から差し替えをするので、DeviceKindsCopy を Name として登録しておきます。

作成した CSV ビューはこんな感じです。今回も Name は後から修正します。

前回と同様に CSV に書き出し後、リレーションの URL 削除をしてしまいます。
sed 's/ (https:\/\/www.notion.so[^)]*)//g' Set\ lists\ babb7c61c5364530bb06525df5a5ad1d.csv | sed 's/\([0-9][0-9]*\)\/\([0-9][0-9]*\)\/\([0-9][0-9]*\)/\1-\2-\3/g' | sed 's/ → /\//g' > SetLists.csv
変換結果は以下のようになります。昨日と同様にここからリレーションを設定します。
Type,Device,DeviceKinds,Name,Concert,Performances アルバム(NEW SEASON),NEW SEASON,アルバム,アルバム,, シングル(NEW SEASON),NEW SEASON,EPシングル,EPシングル,, Set list A,,,,渋谷ライブイン ファーストライブ,01 Set list A,,,,"「OVERHEAT. NIGHT」, 「GET SMILE」",02
SetLists の作成 & インポート
森高千里DBの下に作成したいので、また Cmd-Opt-9 で新規ページを作成します。この新規ページを開き、インポートを実施しました。

インポートを実行しました。

リレーションの作成
名前を修正するのを忘れたので、Concert, Devices, Performances の名前を DeviceStr, ConcertStr, PerformancesStr に変更しておきます。その後、Concert と Device リレーションを追加します。Concert は1対多の関係となります。このため、1ページ制限を付加しています。Devices は同じセットリストが複数のものに繋がることがあるので、こちらは多対多となります(後から気づいて修正しました)。また双方向リレーションも追加します。


一方で、Performances データベースに SetLists へのリレーションを追加します。Performances 側で 1 ページの制限を付けたいので、こちら側から設定します。

ここまでやって、Device type をコピーし忘れたので、インポートからやり直しました。スクリーンショットを撮り直すのは大変なので、このままにします。
Notion API で Concert, Devices, Performances データを準備
今回は流石に複数プロパティから id を取得したりする必要があり、かなり面倒な処理となるので、スクリプトを記載しました。Device は Name と Device type で一意のページを取得します。Concert は Name だけで一意のページを取得できますが、Performances は数値しかありません。そのため、Concert の Name と Num でハッシュを作り、一意にページを特定します。
#! /usr/bin/env ruby require "notion_ruby_mapping" include NotionRubyMapping NotionRubyMapping.configure { |c| c.token = ENV["NOTION_API_KEY"] } devices_db = Database.find "236d8e4e98ab80e0b548f6e419a81edb" devices_id_hash = devices_db.query_database.each_with_object({}) do |device, hash| name = device.properties["Name"].full_text device_type = device.properties["Device type"].select["name"] hash[[name, device_type]] = device.id end concerts_db = Database.find "239d8e4e98ab806186e0e6e9a36b14ff" concerts_id_hash = concerts_db.query_database.each_with_object({}) do |concert, hash| name = concert.properties["Name"].full_text hash[name] = concert.id end performances_db = Database.find "23cd8e4e98ab8049a856c05ad8eac93a" performances_id_hash = performances_db.query_database.each_with_object({}) do |performance, hash| name = performance.properties["Name"].full_text num, concert_name, = name.split " " hash[[num.to_i, concert_name]] = performance.id end set_lists_db = Database.find "23dd8e4e98ab80739da0d79d60a9f905" cp = set_lists_db.properties["Concert"] dp = set_lists_db.properties["Devices"] query = cp.filter_is_empty.and(dp.filter_is_empty) set_lists_db.query_database(query).each do |sl| p sl.id sp = sl.properties if !(devices_str = sp["DeviceStr"].full_text).empty? device_type = sp["Device type"].full_text devices_str.split(", ").each do |device_str| if (device = devices_id_hash[[device_str, device_type]]) sp["Devices"].relation = [device] p device_str, device_type end end elsif !(concert_str = sp["ConcertStr"].full_text).empty? if (concert = concerts_id_hash[concert_str]) sp["Concert"].relation = [concert] p concert_str if (performances_str = sp["PerformancesStr"].full_text) nums = performances_str.split(", ").map(&:to_i) ids = nums.map { |num| performances_id_hash[[num, concert_str]] } sp["Performances"].relation = ids p concert_str, nums end end end sl.save end
実行結果は以下のようになりました。
ruby relation_for_set_list.rb "23dd8e4e98ab81fdb8c9eb4032cb01b8" "23dd8e4e98ab812fb8e0e5d5e752be5f" "「サバサバ」ツアー" "「サバサバ」ツアー" [2, 3, 4, 6, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27] "23dd8e4e98ab817bb138d95ad7b1d5a5" "23dd8e4e98ab813cb605c44c45235813" "Live GiRLPOP ACT 22" "Live GiRLPOP ACT 22" [1] "23dd8e4e98ab817bb3d8fbad98769923" "Act Against AIDS '97 ついに「THE VARIETY 5」" "Act Against AIDS '97 ついに「THE VARIETY 5」" [1] "23dd8e4e98ab81d88fd3dc227f8ce91f" "23dd8e4e98ab81968ba7c7dcdb44b42e" "「PEACHBERRY SHOW」ツアー" "「PEACHBERRY SHOW」ツアー" [14]
結果として以下のようにリレーションが設定できました。

必要なくなったプロパティを削除し、Type を綺麗に整理しました。

Name を自動設定するオートメーション
昨日の Performance と同様に Name を Type と Device または Concert から自動設定するようにしてみます。

ここで設定した値は以下のように設定しました。

オートメーションの確認
試しに最初の一つだけタイトルの文字列を消してみたところ、想定通りのタイトルが設定されました。

あとは全てのタイトルを削除したところ、一気にタイトルが自動設定されました。

おわりに
Set Lists については単一プロパティでは一意にリレーションを設定できませんでした。複数プロパティを使ってページを特定することで、207件の SetLists を手動で設定しなくてよくなり助かりました。