type holyshared = Engineer<mixed>

技術的なことなど色々

Dinosaur Jrのドキュメンタリー映画

3月25日から上映しているようで、Youtubeの予告で知って見に行きました。 Cinem@rt-新宿でやってたので遠出しなくて住んだのがよかったです。

dinosaurjrmovie.com

1時間20分くらいで、バンドの結成から解散後、さらに再結成までのドキュメンタリー映画で昔のライブの映像とかが見れて嬉しかったです。

物販ではT-shirtsとかトートバッグが売っていて、欲しかった紫色のT-shirtsがなかったので色違いの黒とキャップを買いました。 紫はやっぱり人気ぽくて、見る前に先に買っておけばよかったです。

Goods

Dinosaur Jrのギターの音がすごい好きで、Green Mind、Hand It Overは高校生の頃からずっと聴いていて、今聴いても飽きないです

2021年の靴の着用回数を集計した

f:id:holyshared:20220111190201j:plain

毎年恒例の履いた靴の集計をしてみました。
2021年は追加されたのが7足で、手放したのが3足なので増減があんまりなかったようです。

2020年が17足買っていたので、少なく感じます。
相変わらずレザーの靴は買っているようです。

2021年の特徴として、ジョギング用のBROOCKSの靴が増えています。
これは運動のウォーキングに加えて、5kmくらいジョギングすることが増えたので、購入したものです。

来年としては継続して履いているものが増えたので、購入は控えつつ手放すものを吟味していく予定です。
流石に40足あると置き場に困るのでなるべく減らしていきたいです。

以前から履いている靴

No. モデル ブランド 2021年までの着用回数 2021年の着用回数
1 HunterⅡ Rolling dub trio 27 23
2 ASAHI M020 ASAHI 33 27
3 Black Grain 6 Eye Derby Boot SOLOVAIR 30 25
4 LAW NPS shoes 32 25
5 Harry BROTHER BRIDGE 48 29
6 Jackie Ballband 39 27
7 ASAHI M022 ASAHI 41 27
8 6inch Boots Reverse Black Odessa Chippewa 39 25
9 BOYS KATSUYA TOKUNAGA 39 25
10 HI BASKET W MoonStar 45 28
11 GARRISON TRAIL GORE-TEX HIKING SHOES Timberland 39 25
12 CYPRESS Dry Bones 44 24
13 M-43 SERVICE SHOES JOHN LOFGREN 45 24
14 BERLIN BROTHER BRIDGE 52 25
15 CAMERON ESSENTIAL NPS shoes 44 24
16 CONISTON Crockett&Jones 54 25
17 Morgan BROTHER BRIDGE 53 25
18 1930s Sport Boot Redwing 54 24
19 Spider Scotch Grain 52 24
20 Custom Jobmaster 38LTT Wesco 53 25
21 Military Apron Derby Boots Sanders 57 24
22 Enginier Slip on Tokyo Sandals 197 73
23 442 MILITARY CAP TOE OXFORD RAMSEY 81 24
24 DOBULE MONK SANDAL Tokyo Sandals 269 87
25 ROOTS Rolling dub trio 89 29
26 Norwogian Split Pistorelo 67 24
27 Irish Setter Redwing 84 28
28 OB-8593GT 栃木レザープレーンミッドブーツ SLOW WEAR LION 75 25
29 OB-8593G オイルドレザープレーンMIDブーツ SLOW WEAR LION 73 25
30 6inch Service Boots Chippewa 73 24
31 McCLOUD BROTHER BRIDGE 78 25
32 JAMES BROTHER BRIDGE 83 26
33 6inch HotShot Nicks 74 24

新しく購入した靴

No. モデル ブランド 2021年までの着用回数 2021年の着用回数
1 Ghost14 BROOCKS 13 13
2 Overstone Hi Derby Crown Northampton 27 27
3 Neon Blue 8 Eye Derby Boot SOLOVAIR 20 20
4 6Eye Astronaut Boot SOLOVAIR 21 21
5 “ATHLETIC SHOES”HIGH CUT MODEL BUZZ RICKSON'S 21 21
6 Solar Wave Leather/Fabric Mid Hiker Boots Timberland 31 31
7 飛鳥ホールカット KOTOKA 36 36

手放した靴

No. モデル ブランド 2021年までの着用回数 2021年の着用回数
1 Postal 706V2 New Balance 18 7
2 MEXICO 66 Onitsuka Tiger 19 7
3 Chukka boots Berwick 27 7

OuraRing3が届いた

Gen2でも困らなかったのですが、アプリの画面に通知がずっと出てくるので購入してみました。
リングサイズは、今使っているものと変わらず装着感も違和感がないです。

充電器がGen3から変わってるぽくて、充電が完了するとグリーンに変わるみたいです。

後は前に使っていたモデルは、Donateできるぽくてメールで通知がきてました。
面倒なのでやってはいないです。

ハラ ミュージアム アークに行って来た

前から行きたかったハラ ミュージアム アークに行ってきました 場所は渋川なので、高崎で一泊して午前中に行くことにしました

ホテル周辺

ホテルにチェックイン後は暇だったので本買ったり、近くの高崎市美術館で時間を潰したりして楽しかったです
駅周辺は栄えていてめちゃくちゃ便利そうでした、大宮とか町田の駅前に近い感じです

夕食

夕飯はラーメンを食べたかったので、駅近くのOPAにあるラーメン屋で食べました
ここ数ヶ月全くラーメンを食べてなかったのでめちゃくちゃ上手く感じました

翌日は渋川まで電車でいき、後はタクシーでハラ ミュージアム アークまで行きました
かなり山の麓に近いところで、高原みたいな所で風景がめちゃくちゃ良かったです

帰りは渋川駅まで歩いて帰りましたが、ずっと緩い下り坂が続くのでめちゃくちゃ大変でした
普段7kmぐらい歩くのは平気だったので、いけるかなと思っていましたがバスかタクシーで帰ればよかったです

次来る時は、渋川の付近のホテルに泊まろうかなと思います

Cloudinayの新プラン移行

Cloudinayのプラン上限に達したので、プランを変更してみました。
プランはClassic free planだったのをFree planにしました。

CloudinayのアカウントはHerokuのアドオンで指定していたプランだったので、Cloudinayのアカウントを新規に作成してのプランを変更しました。

作業手順としては下記の通りに進めました。
1. 新規アカウントを作成する
2. 新規アカウントでURLのマッピングを旧アカウントの設定に合わせる
3. S3のバケットの.wellknown/cloudinary/に新アカウントのCloudNameをファイル名にした空のファイルを作成する
4. 新しいURLで画像が変換されるのを確認する
5. herokuの環境変数を変更する
6. アプリケーションで画像が正常に表示されるか確認する
7. S3から旧CloudNameのファイルを消す
8. 旧アカウントを削除する

プラン変更は無事終了しました。
これでしばらく運用できそうです。

css-loaderのバージョンを上げた

webpackのcss-loaderのバージョンを5.xから6.xに変えました。
それに伴いcss内の画像指定が期待した通り変換されなくなったのでwebpackの設定ファイルを変えることで対応しました。

具体的にはwebpackの設定のrulesにasset/resourceを追加する作業です。
この設定によりcss-loaderがcssファイル内で参照している画像を置き換えてくれます。

module.exports = [
  {
    module: {
      rules: [
        {
          test: /\.scss$/,
          use: [
            {
              loader: MiniCssExtractPlugin.loader
            },
            {
              loader: "css-loader",
              options: {
                url: true,
                importLoaders: 2,
              }
            },
            "sass-loader"
          ]
        },
        {
          test: /\.(jpg|jpeg|png|svg|gif|ico)$/,
          type: "asset/resource",
        }
      ],
    },
    plugins: [
      new MiniCssExtractPlugin({}),
    ],
    resolve: {
      extensions: ['.js', '.jsx', '.ts', '.tsx'],
    },
    stats: 'errors-only',
  }
];

asset/resourceをasset/inlineにすると、画像のパスをData URIに置き換えてCSSに画像データを埋め込んでくれます。
ファイルのサイズが小さい場合はこちらでも良いかもしれません。

BigQueryのテーブルに複数のログファイルをロードする

Google Cloud Storageに保存されている複数のファイルをBigQueryのテーブルに読み込もうとして、エラーが発生するので調査してみました。
エラーはテーブルにレコードが挿入できないエラーで、フォーマットが当初おかしいのかと思っていました。

Error while reading data, error message: JSON table encountered too many errors, giving up. Rows: 1; errors: 1. Please look into the errors[] collection for more details.
Error while reading data, error message: JSON processing encountered too many errors, giving up. Rows: 1; errors: 1; max bad: 0; error percent: 0
Error while reading data, error message: JSON parsing error in row starting at position 0: Could not convert value to string. Field: sign_in_count; Value: 12

しかしファイルを調べてみてもおかしいところはありません。
調べた結果、スキーマの構造が最初に処理するファイルによってスキーマが決定されていそうでした。

例えば、次のようなログファイルがあった場合、sign_int_countがNullableであることはわかりますが、INTEGERというデータ型まで特定するのは困難です。
代わりにデータ型はNullableなSTRING扱いになるようです。

{ "id": "a", "name": "demo1",  sign_in_count: null, "createdAt": "2021-02-17 07:33:05 UTC", "updatedAt": null }

次のようだとおそらくNullableなINTEGERであることは推測できます。
なぜなら、sign_in_countに2が含まれていて、数値であることがわかるからです。

{ "id": "a", "name": "demo1",  sign_in_count: null, "createdAt": "2021-02-17 07:33:05 UTC", "updatedAt": null }
{ "id": "b", "name": "demo2",  sign_in_count: 2, "createdAt": "2021-02-17 07:33:05 UTC", "updatedAt": null }

今までだと単一のファイルで読み込むことが多く、問題が出ませんでした。
それは単一のファイルだとフィールドのデータパターンが全部収集できるので、フィールドのデータ型が推測しやすかったからだと思います。

解決方法

この問題を解決する為に、読み込み時にスキーマを明示的に指定するようにしました。
明示的に指定することで、正しく読み込むことができます。
200ファイル近くのファイル読み込んでみましたが特に問題は起きませんでした。

その代わりautodetectのメリットがなくなります。

import { BigQuery } from '@google-cloud/bigquery'
import { Storage, File } from '@google-cloud/storage'

const storage = new Storage({ projectId: process.env.GCP_PROJECT_ID })
const bigQuery = new BigQuery({ projectId: process.env.GCP_PROJECT_ID })

const logFilesOf = async (logDate: string) => {
  const prefix = `logs/${logDate}/`
  const bucket = storage.bucket(process.env.GCP_BACKUP_BUCKET_NAME!)
  const [files] = await bucket.getFiles({ prefix })
  return files
    .filter((file: File) => file.name !== prefix)
    .filter((file: File) => {
      const size = Number(file.metadata.size)
      return size > 0
    })
}

const loadFilesOf = async (tableId: string, logDate: string) => {
  const files = await logFilesOf(logDate)

  if (files.length <= 0) {
    return
  }

  const table = bigQuery.dataset('example_dataset').table(tableId)

  return table.createLoadJob(files as any, {
    sourceFormat: 'NEWLINE_DELIMITED_JSON',
    autodetect: true,
    writeDisposition: 'WRITE_TRUNCATE',
    schema: {
      fields: [
        {
          name: 'id',
          type: 'STRING',
          mode: 'REQUIRED',
        },
        {
          name: 'name',
          type: 'STRING',
          mode: 'REQUIRED',
        },
        {
          name: 'sign_in_count',
          type: 'INTEGER',
        },
        {
          name: 'createdAt',
          type: 'STRING',
          mode: 'REQUIRED',
        },
        {
          name: 'updatedAt',
          type: 'STRING',
        },
      ],
    },
  })
}

loadFilesOf('example', '2021-08-09')
  .then(() => {
    console.log('done')
  })
  .catch((err: Error) => {
    console.log(err.stack)
  })