あきろぐ

いろいろめもするよ🐈🐈🐈

【Rails】カラムの中身を別のカラムにコピーする3パターン

1つ目

あるテーブルに新しくカラムを追加し、既存のカラムデータを新規カラムにコピーする

ModelName.update_all(new_column = old_column)

2つ目

テーブルサイズが大きい場合、レコードを分割して処理を実行することも可能

ModelName.in_batches(of: 10000) do | model_name|
  model_name.update_all(new_column = old_column)
  sleep 1
end

railsdoc.com

3つ目

既存の複数カラムデータをconcatして新規カラムにコピーする

ModelName.update_all('new_column = CONCAT(IFNULL(old_column1, ""), IFNULL((old_column2, ""))')

コピー元のカラムにnullが含まれている場合、CONCATされないのでIFNULLで回避する必要がある。

PostgreSQLを入れ直したらrails db:prepareできなくなった

何が起きたのか

PostgreSQLが立ち上がらなくなってしまったので、再度インストールし直した後rails db:prepareを実行したところ、以下のようなエラーが発生した。

rails aborted!
LoadError: dlopen(/Users/xxx/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/pg-1.3.1/lib/pg_ext.bundle, 0x0009): Library not loaded: /opt/homebrew/opt/postgresql/lib/libpq.5.dylib
  Referenced from: /Users/xxx/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/pg-1.3.1/lib/pg_ext.bundle
  Reason: tried: '/opt/homebrew/opt/postgresql/lib/libpq.5.dylib' (no such file), '/usr/local/lib/libpq.5.dylib' (no such file), '/usr/lib/libpq.5.dylib' (no such file) - /Users/xxx/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/pg-1.3.1/lib/pg_ext.bundle

エラーの内容としては、以下のファイルがディレクトリ内になくて実行できないとのこと

原因

PostgreSQLを再度インストールしたときにバージョンが上がってしまったことにより、PostgreSQLディレクトリのパスが/opt/homebrew/opt/postgresql@14/変更されてしまったこと。

🍒~$ ls /opt/homebrew/opt/postgresql@14/lib/postgresql@14
_int.so             hstore_plperl.so        libpq.dylib         refint.so
adminpack.so            insert_username.so      libpqwalreceiver.so     seg.so
amcheck.so          isn.so              lo.so               sslinfo.so
auth_delay.so           jsonb_plperl.so         ltree.so            tablefunc.so
auto_explain.so         latin2_and_win1250.so       moddatetime.so          tcn.so
autoinc.so          latin_and_mic.so        old_snapshot.so         test_decoding.so
bloom.so            libecpg.6.14.dylib      pageinspect.so          tsm_system_rows.so
bool_plperl.so          libecpg.6.dylib         passwordcheck.so        tsm_system_time.so
btree_gin.so            libecpg.a           pg_buffercache.so       unaccent.so
btree_gist.so           libecpg.dylib           pg_freespacemap.so      utf8_and_big5.so
citext.so           libecpg_compat.3.14.dylib   pg_prewarm.so           utf8_and_cyrillic.so
cube.so             libecpg_compat.3.dylib      pg_stat_statements.so       utf8_and_euc2004.so
cyrillic_and_mic.so     libecpg_compat.a        pg_surgery.so           utf8_and_euc_cn.so
dblink.so           libecpg_compat.dylib        pg_trgm.so          utf8_and_euc_jp.so
dict_int.so         libpgcommon.a           pg_visibility.so        utf8_and_euc_kr.so
dict_snowball.so        libpgcommon_shlib.a     pgcrypto.so         utf8_and_euc_tw.so
dict_xsyn.so            libpgfeutils.a          pgoutput.so         utf8_and_gb18030.so
earthdistance.so        libpgport.a         pgrowlocks.so           utf8_and_gbk.so
euc2004_sjis2004.so     libpgport_shlib.a       pgstattuple.so          utf8_and_iso8859.so
euc_cn_and_mic.so       libpgtypes.3.14.dylib       pgxml.so            utf8_and_iso8859_1.so
euc_jp_and_sjis.so      libpgtypes.3.dylib      pgxs                utf8_and_johab.so
euc_kr_and_mic.so       libpgtypes.a            pkgconfig           utf8_and_sjis.so
euc_tw_and_big5.so      libpgtypes.dylib        plperl.so           utf8_and_sjis2004.so
file_fdw.so         libpq.5.14.dylib        plpgsql.so          utf8_and_uhc.so
fuzzystrmatch.so        libpq.5.dylib           pltcl.so            utf8_and_win.so
hstore.so           libpq.a             postgres_fdw.so         uuid-ossp.so

解決策

pgをアンインストールした後、再度インストールする

gem uninstall pg
bundle install

Google CalendarをCLIで扱えるnpmを作成しました

作ったもの

Google CalendarCLIで扱えるnpmを公開しました。機能はシンプルですが、ターミナル上でGoogle Calendarのイベントを表示、登録、編集、削除することができます。

www.npmjs.com

作成動機

最近Javascriptを勉強していたこともあり、外部APIを使って何かCLIツールとして便利なものを作ってみたいと思ったからです。 他にも色々案は考えていましたが、大体二番煎じになってしまうものしか思いつかず、一番アイディアだしに苦労しました。

結構無難ではあるけど、自分の観測内ではGoogle Calendarをいい感じに扱えるnpmは存在してなさそうだったので、これに決定しました。 Google Calendar APIを使うためにGCPでService accountを作成したりと、普段AWSしか触っていない身としては勉強になりそうだなと思ったのも1つの動機です。

Google Calendar + Javascriptをいい感じに組み合わせてgoogler-jsと命名しました。

悩んだところ

GCPよく分からん

GCP側のOAuth認証の同意画面で何が原因か分からないエラーに遭遇し、数時間時間を溶かしました。 結局アプリ名がよくなかったみたいです、ハイフン使うとだめだったみたい?(エラーメッセージに含めてほしい)

OAuth認証使うかサービスアカウントを使うか

OAuth認証だと期限が切れると毎回認証作業が発生するのがめんどくさいので、サービスアカウント使う方法を調べていたのですが、サンプルには載っていなくて探すのに時間かかりました。

レポジトリのREADMEに記載あったので無事サービスアカウント使った認証方法で実装できました。

github.com

CLIツールとしての使いやすさ

CLIGoogle Calendarを操作できるとはいえ、やっぱり使いにくいとブラウザ上で操作したほうが早いとなってしまい意味がないので、ある程度の操作性が担保されるように実装するのは考えどころでした。

ワンライナーで必要な情報を指定して実行するのもありですが、対話的インターフェースの方が操作しやすいかと思ったのでenquirerを導入し、入力値に不正な値が含まれていたら弾かれるようにバリデーションもしっかり実装しました。

後は、使っていてほっこりするようにネコチャンを召喚させてます。

実行イメージはこちら(途中入力ミスしてますがw)

googler-jsの今後

まだ最低限しか機能がないので、イベントを検索するなどもう少し機能拡張したいなと思っています。

CodeDeployで"TaskDefinitionTemplateArtifact"パラメータを見直してくれって言われたときの回避策

どんなエラー?

遭遇したエラーは以下の通り。

タスク定義の検証に失敗したので、CodePipelineのアクションに記述されている"TaskDefinitionTemplateArtifact"のタスク定義を見直してほしいとのこと。 別のデプロイパイプラインも同じ構成となっているのに関わらず、特定のデプロイパイプラインのCodeDeployだけ失敗する状況だった。

Failed to validate the task definition. Check the task definition in the
"TaskDefinitionTemplateArtifact" parameter for your pipeline action
and verify the configuration details for the ECS service.

デプロイパイプラインはCodePipeline+CodeBuild+CodeDeployで実現されており、ECSのタスク定義はCodeBuildのArtifactとして出力されたものをCodeDeployで使っている構成となっている。

f:id:akngo22:20220305001258p:plain
デプロイパイプラインのアーキテクチャ

原因

このエラーの原因について調べたところ、タスク定義の環境変数でマルチバイト文字が含まれているとエラーになるらしいことが発覚した。 該当のタスク定義を見直してみると全角の環境変数の値が含まれていたのでこれが原因そう。

zuntan02.hateblo.jp

回避策

環境変数の値をマルチバイト文字から変更することはできないので、タスク定義で直接環境変数の値をベタ書きするのではなく、ParameterStoreの中にマルチバイト文字を入れ参照する形に変更した。 このように環境変数の参照方法を変更することで上記のエラーが出なくなったことが確認できた。

ParameterStoreに値を入れるとSecrets配列の中に対象の環境変数を定義することになるが、現状はこれが手っ取り早い回避策かなと思う。