まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

毎年恒例のマンホールマップ年間アクセスランキングを発表します。2023 年にマンホールマップでもっとも人気のあったマンホール蓋をベスト10形式で紹介します。また今年新たに投稿された蓋の中で最も人気があった「新人賞」と、今年最も多くの蓋画像を投稿いただいた方「最多投稿賞」を紹介します。

集計のルールとしては 2022/12/21 から 2023/12/20 までの集計期間における、PC およびスマホのブラウザから単独ページとしてのアクセス数を集計しています。ページビューとしての集計なので、例えば同じページの画面をリロードした場合は1回とだけカウントされます。

なお、過去9回の結果はこちらを参照ください:
2014 マンホールマップ年間アクセス数ランキング
2015 マンホールマップ年間アクセス数ランキング
2016 マンホールマップ年間アクセス数ランキング
2017 マンホールマップ年間アクセス数ランキング
2018 マンホールマップ年間アクセス数ランキング
2019 マンホールマップ年間アクセス数ランキング
2020 マンホールマップ年間アクセス数ランキング
2021 マンホールマップ年間アクセス数ランキング
2022 マンホールマップ年間アクセス数ランキング


2023 年の大きな変化
恒例の発表に移る前に1つお伝えしておくことがあります。2023 年もいろいろなニュースがありましたが、マンホールマップ的には「ツイッターが消滅し、X へ移行した」ことの影響をまともに受けた年となりました。

ツイッターを利用している立場でも、単なる名称変更に留まらない(利用できる機能の制限や有料化などの)変化があったと思いますが、ツイッターを使ってアプリケーションやサービスを作っている立場では数々の受け止めきれない変化に飲み込まれることになりました。結果的に 2023 年のマンホールマップは数日間ログインができない期間が生じてしまったり、(これは今でも影響を受けたままですが)投稿者のアイコンが表示できなくなったりしました。#manhotalk_bot もこの影響を受けてしまっていますよね。利用してくれる皆さんへの影響が生じてしまった点については改めてこの場で陳謝させていただきます。

今でも X は「消滅するかも・・」みたいな噂がたまに流れたり、実際に不具合でたまに止まったりしては「ついにその時が来たか・・」と思ってはいつの間にか治ってたりと、不穏な空気が残ったままではあるのですが、一方で当初制限を受けると言われていた機能が結局使えるままになっていたりもするので、とりあえず状況は落ち着きつつあるのかな・・と期待しながら今後もマンホールマップの運用を続けていこうと思っています。

では今年の各賞を発表します。


2023 最多投稿賞

2023 年は上述のログイン不可期間もあり、実質的に例年よりも少ない投稿期間となっていましたが、集計期間中に 401 枚ものマンホール画像が投稿されました。 今年も多くの皆様からの投稿によってマンホールマップは成長し続けることができました。改めて投稿に協力いただいた皆様、ありがとうございました。

そして今年マンホールマップに最も多くの画像を投稿いただいたユーザーに与えられる賞、それが最多投稿賞です。今年もコンスタントに投稿いただいた 42ER03 様が最多投稿でした(3年連続6回目)。最近は 42ER03 様からのメッセージでマンホールマップが止まっていることに気付くこともあり(苦笑)、色々な意味で今年も感謝の限りでございます。 m(__)m

なお2位は carz82902686 様、3位は私 dotnsf でした(私は昨年は4位でした。今年は関西方面への出張が復活したことも含め、広島や京都も訪ねるなど西日本での蓋活動が多かった1年でした)。


2023 新人賞&総合ランキングベスト10

いよいよ 2023 年マンホールマップ年間アクセス数ランキングを発表する時がやってまいりました。総合ランキング1位となる MVM(Most Variable Manhole) の座はどの蓋に!?


まずは新人賞です。今年投稿された中で最もアクセス数の多かった蓋を紹介します。こちらです:

市区町村投稿者画像
東京都台東区 minamu450


浅草名物「雷門」からも近い墨田川沿いに設置された古典歌舞伎「助六」の演目の1シーンが描かれた美しい蓋です。東京23区のソメイヨシノ蓋同様、ユリカモメに囲まれています。私も職場が比較的近いこともあって実物を見に行ってきました。

実は minamu450 さん(このアカウントで)が 2023 年に投稿した唯一の蓋が2月のこれでした。新人賞おめでとうございます。


では改めて 2023 年のランキングを発表します。まずは 10 ~ 4 位です。
が、今年も10位付近は大激戦で、10位は3つの蓋が同数でした(なんと2年連続!そして次点は1アクセス差!!)。その大混戦から抜け出して滑り込んだ第10位!

順位昨年順位市区町村投稿者画像
10 - 東京都清瀬市 dotnsf

気象庁・マスコットキャラクターの「はれるん」が描かれた東京都清瀬市、気象衛星センター内のカラーマンホールです。投稿者はなのですが撮影者は別で、いわゆる代理投稿です(おめでとー!)。実はこの気象衛星センター内は撮影していい箇所といけない箇所があって、この蓋は本当に大丈夫なのかどうか・・・ ともあれ年間トップ10入り、おめでとー!!!!


2つ目の第10位!

順位昨年順位市区町村投稿者画像
10 - 大阪府門真市 SakiYumeno

門真市のイメージキャラクター「ガラスケ」が描かれた大阪府門真市のデザインマンホールです。撮影者はたまにイベントでお会いする SakiYumeno さん。門真は私も仕事でよく行く場所の1つなのですが、このデザインは見たことありませんでした。今度いこ。 というわけで初の年間トップ10入り(ですよね?)、おめでとうございます!!


最後、3つ目の第10位!

順位昨年順位市区町村投稿者画像
10 - 埼玉県所沢市 42ER03

武蔵坊弁慶が白紙の勧進帳を見て「清き水となり大地をうるおせ」と読んだとされる歌舞伎でも有名なシーンが描かれたマンホール、投稿者は今年の(も)最多投稿者でもある 42ER03 さまです。

・・ただ、この蓋はマンホールマップ上では埼玉県所沢市に投稿されているのですが、一般的には石川県小松市の蓋として有名なやつだと思っています。越境蓋なのかな? このあたり続報があればいただきたいです(必要であればこのブログも修正します)。


第9位!

順位昨年順位市区町村投稿者画像
9 - 東京都世田谷区 EkikaraManhole

EkikaraManhole 大先生による、いわゆる「ご本人登場」の蓋投稿です。かつて世田谷区を流れていた北沢川を暗渠化して整備された緑道にカラー設置されたかつての姿。昔はこの辺りは蛍やメダカが生息してたんですかね。

第8位!

順位昨年順位市区町村投稿者画像
8 - 静岡県熱海市 tenore0

本ランキング初の地味蓋登場。静岡県熱海市に設置された「ガス」の蓋、なのですが、その正体がイマイチわかりません。投稿者の tenore0 さんも「ちょっと自信がないのですが、熱海市内の都市ガスを取り扱っている会社のふただと思います」と書かれてますし、「熱海ガス」という会社が存在することも分かっているのですが、では本当に熱海ガスの蓋か?と言われると、私も分かりませんでした。真ん中のマークは EX と書かれているようにも見えるんだけど、これはヒントになってるんだろうか・・詳細分かる人いる?


第7位!

順位昨年順位市区町村投稿者画像
7 9 群馬県高崎市 TMW_papa

昨年は9位だった、群馬県高崎市の「ぐんまちゃん」サッカーデザインです。2015 年、2016 年にも連続トップ10入りしている、マンホールマップでも指折りの人気蓋が、今年も多くのアクセスを記録しました。投稿者は TMW_papa さんです。

第6位!

順位昨年順位市区町村投稿者画像
6 3 岩手県盛岡市 minamu4545


昨年3位だった盛岡市の「わんこきょうだい」蓋が今年も6位でランクインしました。去年も言った気がしますが、わんこずんだだけはヤバそうな気がしています。投稿者は最多投稿賞でも常連の minamu4545 さん(minamu450 さん)です。


第5位!

順位昨年順位市区町村投稿者画像
5 - 東京都世田谷区 jishiha

世田谷区から2つ目のランクイン!玉川電気鉄道をあしらったデザインマンホール(?)。投稿者はモバイル版マンホールマップを開発されていた jishiha さんです。どーも、ご無沙汰しております。 そんなこのマンホール、石畳に紛れ込ませた感じのこれをデザイン蓋に分類していいのか迷いますが、玉電でググった人が多かったんですかね?ともあれ何故か 2023 年に多くのアクセスを集める結果となりました。


第4位!

順位昨年順位市区町村投稿者画像
4 - 高知県高知市 minamu4545


名物のカツオが飛び跳ねる様子がデザインされた高知市の蓋です。デザインは公募らしく、よさこいアイテムの鳴子も鮮やかにデザインされているのがわかります。マンホールマップへの投稿は 2017 年でした。これまでランキングに入ることはなかったのですが、今年突然のブレーク!といった所でしょうか。 投稿者はこれも minamu4545 さんです。



ここからはトップ3の発表です。第3位!!

順位昨年順位市区町村投稿者画像
3 - 東京都台東区 minamu450


上の新人賞でも紹介した助六夢通りの蓋が 2023 年の総合3位でした。このデザイン蓋が設置されているのは一枚だけですが、浅草雷門からスカイツリーに向かう道の途中、墨田川を渡る直前あたりという、人通りの多そうな場所に設置されています。今後も人気が続くことが考えられる蓋だと思っています。


第2位!!!

順位昨年順位市区町村投稿者画像
2 - 北海道札幌市 yanapong


実は昨年の10位にはカラー版がランクインしていたのですが、なぜかその地味版が 2023 年の総合2位となるアクセスを記録しました。こういう解説に困るアクセス順位になるのがマンホールマップです。 というわけで、有名な札幌市の時計台がデザインされた人気マンホール(の地味版)が何故か大量のアクセスを集めていました。 投稿はこの界隈では有名な yanapong さんでした。やなぽんさんは(別の蓋ですが)2018 年まで4年連続トップ10入りを記録した「リスのクリちゃん」マンホールの投稿者でもあり、その時以来5年ぶりのトップ10入りとなりました。


さて 2023 年の MVM はどの蓋に? 注目の第1位!!!!
























順位昨年順位市区町村投稿者画像
1 1 香川県東かがわ市 minamu4545


ついに歴史が動きました。マンホールマップ年間アクセスランキング初の2連覇達成、香川県東かがわ市に設置され、昨年ポケ蓋では初の1位を記録した「うどん県のヤドン」マンホールが 2023 年マンホールマップ年間アクセスランキングの1位を記録しました。投稿者である minamu4545 さん(minamu450 さん)、おめでとうございます!!


ちなみに1位となったヤドンのマンホール蓋のアクセス数は「ダントツ」でした。2位以下の混戦を数馬身離しての1着という感じで、この人気はもうしばらく続くのではないかと思っています。



さて来年のマンホールマップランキングはどうなるのでしょう? 3連覇はあるのか? そしてツイッターは大丈夫なのか? 期待と不安が入り混じります。

では辰年となる 2024 年も引き続きマンホールマップをよろしくおねがいします。

(↓ これも minamu4545 様投稿蓋です)



自作サービスを開発している途中で調査した内容のアウトプットです。

Node.js を使って PostgreSQL データベースを操作する場合、pg(node-postgres) ライブラリを使うのが定番だと思っています。実際これまで何度も使ってきているし、データの読み書き更新削除といった作業で特に困ったことはありませんでした。

しかし今回ちょっとしたことで詰まってしまいました。結果的には解決できたのですが、データベース内に定義されたテーブルの、列の定義情報を調べたいと思った時に「これどうやるんだろ?」となってしまいました。

もう少し具体的に説明します。例えば以下のような SQL を使って items テーブルを作成したとします:
CREATE TABLE items( id varchar(50) primary key, name varchar(100) not null, price int default 0, body text, image bytea, datetime timestamp );

このようにして作成した items テーブルの各列の定義情報(上の例の青字部分)を取り出す方法が分からなかったのでした(列名だけであれば select 文の実行結果の中に含まれるので、1行でもレコードが登録されていればそこから分かる、ということは知っていました。が、レコードが1件も登録されていないケースだったり、列名以外の型の情報まで必要な場合の取得方法が分かっていませんでした)。ちなみにこの情報は psql コマンドを使った場合はログイン後に
# \d items

というコマンドを実行することで取得できることは知っていました("items" の部分に知りたいテーブル名を指定して実行します):
db=# \d items
                          Table "public.items"
  Column  |            Type             | Collation | Nullable | Default
----------+-----------------------------+-----------+----------+---------
 id       | character varying(50)       |           | not null |
 name     | character varying(100)      |           | not null |
 price    | integer                     |           |          | 0
 body     | text                        |           |          |
 image    | bytea                       |           |          |
 datetime | timestamp without time zone |           |          |
Indexes:
    "items_pkey" PRIMARY KEY, btree (id)

この方法を知っていたので、これまであまり気にすることもありませんでした。ところがこれはあくまで psql コマンドを利用する際のコマンドであって、これをそのまま SQL として pg を使って実行すると(SQL ではないので当然ですが)エラーとなってしまいます。ではいったいどうすれば pg でこの情報をプログラムのコード内で取り出すことができるのだろうか・・・ というのが今回のブログエントリのテーマです。


結論として分かったのは、こんな感じでした:
・SQL としては実行結果にすべての列が含まれるような SELECT 文(例: "select * from items")を実行する
・実行結果からレコードを取り出す場合は result.rows を参照するが、実行結果の列情報は result.fields と result._types._types.builtins を参照することで取り出すことができる
・実行結果のレコードが0件でも(1件もレコードが登録されていなくても)、上の方法で列情報を取り出すことはできる

具体的なコードとしてはこのような感じです:
var PG = require( 'pg' );
var pg = new PG.Pool({
  connectionString: "postgres://user:pass@hostname:5432/db",
  idleTimeoutMillis: ( 3 * 86400 * 1000 )
});

  :
  :

if( pg ){
  var conn = await pg.connect();
  if( conn ){
    try{
      var sql = 'select * from items';
      var query = { text: sql, values: [] };
      conn.query( query, function( err, result ){
        if( err ){
          console.log( err );
        }else{
          var fields = r1.result.fields;
          var types = r1.result._types._types.builtins;
          var columns = [];
          fields.forEach( function( f ){
            var dt = Object.keys( types ).reduce( function( r, key ){
              return types[key] === f.dataTypeID ? key : r;
            }, null );
            columns.push( { column_name: f.name, type: dt } );
          });

            :
            :
        }
      });
    }catch( e ){
      console.log( e );
    }finally{
      if( conn ){
        conn.release();
      }
    }
  }
}


赤字の部分の解説をします。まず "postgres://(ユーザー名):(パスワード)@(PostgreSQL サーバー名):(ポート番号)/(DB名)" というフォーマットの接続文字列を使ってデータベースに接続します(正しく接続できるのであれば、このフォーマットである必要はありません)。 そして接続後に "select * from items" というシンプルな SQL を実行して、結果を result という変数で受け取ります。この SQL 実行結果(レコード情報)自体は result.rows という属性に配列形式で格納されているのですが、今回ここは使いません。

この SQL を実行することにより、指定したテーブル(今回の場合は items)の列名とデータ型IDの情報が result.fields に、データ型IDとデータ型の関係を示す表が result._types._types.builtins に格納されているはずです。これらを取り出し、各列のデータ型を ID ではなく文字列に変換しなおして、最終的に columns という配列変数に記録しています。

この columns の実行結果を参照すると、このような値になっているはずです:
    [
      {
        "column_name": "id",
        "type": "VARCHAR"
      },
      {
        "column_name": "name",
        "type": "VARCHAR"
      },
      {
        "column_name": "price",
        "type": "INT4"
      },
      {
        "column_name": "body",
        "type": "TEXT"
      },
      {
        "column_name": "datetime",
        "type": "TIMESTAMP"
      }
    ]

"integer" 型が、より正確な "INT4" という型になっていたりはしますが、当初取得したかった列の定義情報を取得することができました。なお、この方法であれば SQL の実行結果(result.rows)そのものを参照しているわけではないため、実行結果が0件であっても(レコードがまだ1件も登録されていない場合でも)実行できるようです。

サンプルソースコードはこちらからどうぞ:
https://github.com/dotnsf/pg_fieldtype


(2023-12-18 追記)
ちなみに MySQL の場合、その名もズバリの mysql ライブラリを使うのが定番だと思ってますが、こちらの場合はテーブル一覧("show tables")もテーブル定義("desc (テーブル名)")も、CLI で使う命令文をそのまま利用して取得することができるので、深く考えなくてもよいのでした。




このブログエントリは IBM Cloud アドベントカレンダー 2023 に参加しています。12/20 ぶんの記事です(このブログエントリ自体は 12/14 に公開します):
2023112901



IBM Cloud から提供されている機械学習型チャットボット生成の Watson Assistant が、ブランド名称変更により Watsonx Assistant となりました:

https://www.ibm.com/jp-ja/products/watsonx-assistant
2023121401


"Watson Assistant" で検索した結果からブラウズした場合は新ブランドページに推移します:
2023121402



私も「ブランド名の変更があっただけで、中身は変わってないよね?」と思っていました。結論として機能的にはそれほど大きく変わったわけではないのですが、新しくインスタンスを作成した直後の画面が変わっていて、従来のダイアログ機能(インテントやエンティティを定義して会話の流れを作るツールとその機能)を利用する方法が分かりにくくなっていると感じました。これまでの Watson Assistant では普通に使えていたダイアログ機能を新しい UI で使えるようになるまでの手順を以下に紹介します。


まず最初の(名前設定などの)初期設定を一通り実行します。その後に画面左のメニューから下の方にある "Assistant settings" を選択します:
2023121403


画面を下の方にスクロールすると、"Activate dialog" と書かれたボタンがあるのでクリックして、アクティベートします:
2023121404


アクティベート後に再度左メニューを開くと、先ほどまでは表示されていなかった "Dialog" という項目が表示されているはずです。これをクリック:
2023121405


これで従来のダイアログ設計画面が表示されます。ここからインテントやエンティティといった要素を定義できます:
2023121406


一瞬「あれ?ダイアログ無くなった??」とビビりました。 (^^;  よかったよかった。


このページのトップヘ