chevron_left

メインカテゴリーを選択しなおす

cancel
きり丸
フォロー
住所
未設定
出身
未設定
ブログ村参加

2022/07/22

arrow_drop_down
  • GraphQLで存在しないエントリーポイントを指定していると誤解した小ネタ

    始めに 小ネタです。 弊社システムではGraphQLを採用していますが、存在しないmutationを指定していると勘違いしたものを残しておきます。 環境 なし。 実装 次のようなクエリがありました。 mutation createUser($input: CreateUserInput!) { createUserWithRole(input: $input) { } } 私はcreateUserというサーバのmutationエントリーポイントを実行していると判断していました。しかし、実際にはcreateUserWithRoleを実行しています。このcreateUserはクライアントがどのよう…

  • MySQLのJSONテーブル関数は調査に使うと便利

    始めに 最近、不具合調査でAWSのCloudWatchから出力したログを分析および加工するためにDuckDBを使用しています。DuckDBは優秀で自分のやりたいように分析できるのですが、あくまでアプリケーションログをそのまま分析しているだけですので、最終的にはDBのMySQLと突合しないとわからないことが多々あります。 これがDBの値だけを取得するだけなら簡単だったのですが、IPアドレス制限で引っかかったユーザ一名、 該当IPアドレスおよびアクセス時間を出力したい要件だったため、アプリケーションログとDBの値を出力する必要がありました。もちろん、これが1行だけなら次のSQLで簡単に出力できます…

  • FastAPIはORJsonResponseではなく、素直にPydanticでよさそう

    始めに FastAPIはデフォルトではJSONResponseを使用してレスポンスします。FastAPI公式ヘルプにはパフォーマンスを向上させるためにORJSONResponseの使用を提案するページがあります。 fastapi[all]にorjsonが含まれていることもあり、ORJSONResponseを使用して動作確認をしてみたのですが、個人的な使用目的としては早くならなかったのでメモとして残しておくことにします。 ※ ベンチマークの取り方がおかしい、等があったら教えていただきたいです。 Pydantic v2: 3.2411秒 (1000回のリクエスト) ORJSONResponse: …

  • Pythonアプリケーションでタイムゾーンを扱う方法

    始めに 小ネタです。 Pythonでdatetime型を扱うときに、timezone情報を与えることができます。 from datetime import datetime from zoneinfo import ZoneInfo datetime.now(tz=ZoneInfo("UTC")) 簡単にtimezoneに合わせた時刻へ変更できることはメリットではあるのですが、timezoneなし(native datetime)とあり(aware datetime)の時刻を比較すると次のエラーが発生します。 <ExceptionInfo TypeError("can't compare of…

  • AWS CLIでメールアドレスがサプレッションリストにあるかを調べる

    始めに Amazon SESでメールを送った際に、サプレッションリストに登録される可能性があります。サプレッションリストとは、特定のメールアドレスに送信しないようにする仕組みです。登録されるパターンとしては、メールアドレスが存在しない場合や迷惑メールとしてフィルタリングされるBounce、スパムとして報告されるComplaintのどちらかで登録されます。 このサプレッションリストに登録されている限り、該当のお客様にメールを送ることができないのでメールが有効であることを確認したらサプレッションリストを解除する必要があります。ただし、AWS コンソール上ではサプレッションリストから解除はできるもの…

  • Dockerで別環境変数を元にCIとローカル環境で別変数を与える

    始めに 小ネタ。 CI環境を想定して環境変数でCI=TRUEと設定されていれば、AAAと設定して、ローカル環境を想定してCI環境変数が設定されていなければBBBと設定する。 可能な限りCI環境としてはCI=TRUEだけ管理して、具体的にはcompose.yml内部で閉じるような書き方をすることで管理コストを減らそうとしていました。 このようにする書き方を知ったのでブログにします。 環境 Docker Engine 27.4.1 ゴール 環境変数でCIを定義して次のように書けば、CIという環境変数を元にAAAやBBBの環境変数を分岐できます。 export CI= environment: EN…

  • SentryのReplayを任意のタイミングで取得する

    始めに Sentryではフロントでエラーが発生したときに、エラーを調査しやすくなるようにReplay機能があります。この機能は非常に便利なのですが、エラーは発生していないがお客様環境で端末の性能不足やネットワーク性能不足等で正常動作しない場合を追跡できません。 その場合に、任意のタイミングでReplayを取得できる機能がありますので紹介します。 環境 Sentry 2025/03/08時点 @sentry/angular 8.47.0 ユースケース 端末のスペックやネットワークによる不利益を調べたい 特にサーバサイドで取得できないログが欲しいときに 実装 Replayの開始 ※ 実運用ではre…

  • Dockerでlocalhostで他のサービスにアクセスしたい(socat)

    始めに 以前、docker間通信をするときにどのドメイン名やIPを指定すればいいかを調べました。 Dockerのコンテナ間通信をする方法をまとめる - きり丸の技術日記 しかし、例えばS3の署名付きURLを発行した後、フロントから直接署名付きURLでS3にアクセスする場合にはdocker内部ネットワークで解決した名前ではなく、localhostでアクセスさせたいです。 今回の記事では、フロントからS3の操作とバックエンドからS3の操作を統一できるようにするsocatについてまとめます。socatは様々なプロトコルやネットワーク間でデータを転送するためのユーティリティツールで、この問題解決に役立…

  • lockファイルの依存はdevで指定してもmainに影響することがある

    始めに Pythonのpoetry.lockで確認した事象ですが、他のライブラリのlockファイルでも当てはまると思います。仕様上当たり前のことに気づいたのでメモします。 環境 Poetry 2.0.0 fastapi[standard] 0.115.8 httpx 0.28.1 まとめ dev dependenciesでバージョンを指定した場合、main dependenciesにも影響することがある。 やっていたこと FastAPIで非同期のテストをするために、httpxを使用していました。この時にhttpxをバージョン固定した状態でdev dependenciessに加えています。 途中…

  • SQLAlchemyでrefreshがうまくいかなければexpungeを使ってみる

    始めに 特定の環境では再現したのですが、自宅では再現できませんでした。そのため、事象として発生したことのレポートです。 環境 ※ 再現しなかったためなし。 まとめ 基本的にはインスタンスの再更新はrefresh()で問題ないはず。しかし、問題発生したときは一度expunge()でインスタンスを切り離してから再検索する方法もあり。 発生したこと 事前にSQLAlchemyから検索してインスタンスに格納する 同一セッション内で子テーブルのインスタンスを作成する 子テーブルも含めて更新した結果をフロントに返却するために再検索する 1.で取得したインスタンスが返却された 子テーブルが含まれていないイン…

  • mysqldumpは--opt使うなら--single-transactionもつけるのがオススメ

    始めに 本番環境ではないのですが、検証環境でやらかしてしまったインシデントなのでブログにしてお焚き上げします。 やりたかったことは検証環境で不具合が発生していたので、ローカルで検証するために検証環境のDBをエクスポートして、ローカルで再現させることでした。しかし、そのエクスポートを実施したところ、検証環境が機能しなくなったので事象を共有します。 環境 MySQL 8.0.23 まとめ mysqldumpのオプションに--optを付与するなら、--single-transactionもつけるべき。 問題の詳細と解決策 3年ほど使用してきた信頼と実績のある次のコマンドでDBをエクスポートしていまし…

  • Angular18以降のバンドルサイズを分析・可視化する

    始めに Angularで作られたプロジェクトを少しでも初期表示を軽くしようとしていました。lazyloadできる余地がどこにあるのかを調べるためバンドルサイズを分析・可視化しようとしたのですが、Angular18以降では過去に使用していた分析・可視化コマンドがうまく使えなかったのでブログにします。 環境 Angular 19.0.5 実装 次のコマンドでビルドした結果をもとにバンドルサイズを可視化できます。 ng build --stats-json npx esbuild-visualizer --metadata dist/front/stats.json --open 過去の分析が使えな…

  • PythonのParametrizeをもっと便利に使う(pytest.param)

    始めに 小ネタ。 以前、PythonのPytestでParametrizedTestをする記事を書きました。 PythonのPytestでParameterizedTestをする - きり丸の技術日記 調べたときに、もう少し便利できることが分かったのでメモします。 環境 Python 3.13 Pytest 8.3.4 実装 id属性 次のようにするとテストがどのような期待をもつかを人間に伝えることができます。 @pytest.mark.parametrize( "input_birth_day, expected_age", [ (pytest.param(date(2023, 11, 20…

  • AngularのValidatorを変更するならupdateValueAndValidityも呼ぶ

    始めに タイトルの出オチ記事です。 Angularにて、状態によってユーザーをnameで検索したり、emailで検索するinputがありました。 emailの場合は完全一致してほしいので、入力値がemail形式であることを検証し、nameの場合は検証しないようにしたいです。 今回の記事では、処理中に状態を判断してValidatorを変更しつつ、適切な検証を行えるようにします。 環境 Angular 18.0.4 実装 今回の例ではFormControlで実装します。 基本データバインディング HTML HTML側では後で定義するnameOrEmailControlとデータバインドしておきます。…

  • Gitにコミットした中身を検索する (目的行の変更ハッシュを探したいときに)

    始めに 小ネタ。ライブラリを管理しているときに、いつから依存関係に含まれているか、削除されているかを調べるために使用したコマンドを残します。 ユースケース 特定の記載が入ったコミットを探す 環境 git 2.43.0 実装 次のコマンドで、uv.lockに含まれているgreenletライブラリが追加・変更・削除されたコミットを調べます。 git log -S "greenlet" -- uv.lock 終わりに 実際はI18nファイルに記載されていた行が削除されており、そのエラーを調査するために使用しました。 I18nファイルは意識的に整理しないとドンドン膨らんでいくので、定期的に棚卸していた…

  • Dockerをzstdで圧縮する。少しでも軽くしたい

    始めに 先日の記事にて、FastAPIのイメージが1GBになってしまった件を書きました。何か対策できないかと調査していく中で、gzipではなく、zstdで圧縮することで高い圧縮率と高い解凍速度を達成できることを知りました。 今回の記事ではzstdでDockerイメージの圧縮をします。 環境 Docker Engine 27.4.1 Docker Buildx v0.19.3 zstd圧縮を使用するためには、次のバージョンが必要です。 Docker Engine v24.0.0以降 Docker Buildx 0.8.0以降 # バージョン確認用コマンド docker version docke…

  • Rust製のPythonライブラリは軽いと思ってた

    始めに pydantic等のPythonのライブラリはコア部分がRustで書かれていて、Pythonでも十分な処理速度が確保されている、という表現をされることがあります。 そのため、基本的にはRustで作られたライブラリに移行しようとして、テンプレートエンジンのjinja2からminijinjaに移行しようとしました。その過程で気付いたことをメモするだけの記事です。 ※ Pythonのminijinjaについては、試験的な試みでminijinja単体の機能が完全に移行されているわけではないし、処理速度も早いとかは明記されていないので、現時点で移行は勧めないです。 minijinja-py is…

  • 正規表現の\wは使う時は注意。特にOpenAPI

    始めに 正規表現には\wというメタ表現があります。私のプロジェクトではフロントのTypeScript, バックエンドにRuby, Pythonを使用しておりました。 もともとは正規表現を使用しないチェックロジックを使用していましたが、それぞれの言語で実装漏れが発生したこと、横展開の容易さを考慮して正規表現でマッチさせるようにしました。 正規表現であれば、どの言語でも同じようにバリデーションをかけてくれる、そう思っていたところ、大きな勘違いがあったのでブログにします。 環境 JavaScript ES2018 ES2024 Python 3.12 Ruby 2.7 勘違い \wはプログラミング言…

  • JetBrains IDEでcURLをhttpファイルにコピペすると修正してくれる

    始めに 小ネタ。タイトルだけの出オチ記事。 環境 PyCharm 2024.3.1 Professional Edition 例 httpファイルに一般的なREST APIのcURLをコピー&ペーストすると次のように変換されます。 curl -X 'POST' 'http://localhost:8000/tasks' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "title": "クリーニングを取りに行く" }' # curl -X 'POST' # 'http://localhost:800…

  • DataGripで接続先をまとめたい(JetBrains製ならどれでもOK)

    始めに 現在、私は複数のプロジェクトに参画していて、保守作業する際には接続先をプロジェクトごとに切り替える必要があるのですが、すべて接続先をフラットに管理していました。接続先名で無理やりprefixを付与して管理していたのですがDataGripにはフォルダのように管理できる方法があると聞いてその方法をメモします。 なお、DataGripでしか無理、と思っていたのですが他のIDEでも同様の挙動を実装できそうです。 環境 PyCharm Professtional 2024.03 DataGrip 2024.03.2 実装 Database explorerにて、右クリックするとMove to F…

  • nullは不明値なのでnullで一意制約をかけられない

    始めに レコードの有効期間を表示したいときに、start_at, end_atのカラムを用いて表現していました。そして、end_atがnullの場合にアクティブなレコードとして表現しようとしていました。しかし、このやり方ではデータの管理方法に失敗するとアクティブなレコードが複数できてしまう可能性があります。 そのため、アクティブなレコードを1つだけに絞りたかったので、別の主キー + end_atでアクティブなレコードであること表現しようとしました。 しかし、その方法がうまくいかなかったので、同じ轍を踏まないようにブログに残しておきます。 環境 MySQL 8.0 PostgreSQL 17.2…

  • Pythonでflatmapをする

    始めに 小ネタ。PythonでNestした配列に対して、flatなデータにしたいと思った時の処理を残します。 環境 Python 3.13 実装 構造が2階層だけならfrom itertools import chainのlist(chain.from_iterable(input_))を使用する。 from itertools import chain async def test_01(self): input_ = ["1", ["2", "3"]] actual = list(chain.from_iterable(input_)) assert ["1", "2", "3"] == …

  • PyCharmでuvから生成される.venvをSDKに指定する

    始めに 小ネタ。 PyCharmにてryeやuvを直接指定することはまだできませんが、uvから生成される.venvは指定可能だということに気付いていなかったのでそれを記載するだけのメモです。 環境 PyCharm Professional 2024.3 ※ PyCharm Communityでもできるかもしれませんが検証してません。なお、IntelliJ IDEA Ultimateではだめでした。 実装 Python Interpreterを開きます .venvのPythonを指定します 特に指定していない限り、uvを実行したディレクトリの.venv/bin/pythonや.venv/bin/…

  • ビルド時間短縮のために途中ステージをpushする

    始めに 弊社のシステムではECSを使用しているのですが、ここ最近Dockerイメージのビルド時間が大幅に延長されてしまっていました。そのうち、大幅な時間を占めているのがライブラリのインストール時間で、CPUの使用率が高くなって応答が非常に遅くなっていました。 uv.lock等のロックファイルが取り扱われている環境であればインストールでは常に同じライブラリが使用されるものですし、ライブラリインストールが完了した状態のイメージをRepositoryにアップロードすることで短縮することを目指しました。 今回の記事では、Dockerのマルチステージビルドを扱って処理時間を短縮することを目指します。 環…

  • Basic認証込みのNGINXイメージを扱う(beevelop/nginx-basic-auth)

    簡単にBasic認証を実装したり検証したりするためにNGINXを使用しつつ、ついでにBasic認証まで含めているDockerイメージがあったので素振りしました。 環境 Docker 26.0.0 beevelop/nginx-basic-auth 対応 localhost:80にアクセスしたらBASIC認証がかかっており、認証成功したらlocalhost:8080で公開しているサイトに対してリダイレクトしている例です。BASIC認証はデフォルトで次のパスワードになっています。 id foo password bar services: web: image: dockercloud/hello…

  • ハードウェア予約済みのメモリを減らす(軽くなるかも)

    最近、自宅のPCでプログラミングをしていると非常に重くなり、フリーズを頻発してしまっています。そのため、早めに買い換えたいのですが、買い替えるまでに対応できることがないか思考錯誤したときのメモ。 なお、これを行ったことにより改善ができたわけではないので、あとで設定値を微調整をする予定です。 環境 Windows 11 AMD Ryzen 7 5800H with Radeon Graphics メモリ 16GB 対応 自宅のPCがフリーズを頻発する原因はメモリが100%近くまで使用していることだと考えていたので、ハードウェア予約済みのメモリを減らす方向にしました。デフォルトのハードウェア予約済…

  • Pydanticの拡張クラスで小文字化まで行う

    始めに PydanticでEmailStrを拡張するという記事を書きました。今回の記事では、PydanticでEmailStrを拡張するで行ったことをさらに拡張して、大文字小文字のどちらでもパラメータを受け取りつつ、小文字化してアプリケーションで受け取れるようにさらに拡張します。 環境 Python 3.12.7 Pydantic 2.9.2 実装 以前に追加したロジックでvalidate_half_and_full_emailのレスポンスを小文字化します。 from typing import Type, Any import re from pydantic import EmailStr…

  • PydanticでEmailStrを拡張する

    始めに pydanticにはEmailStrというemailを検証するための拡張クラスがあります。しかし、Emailの仕様としてはUTF-8を許容しているものの、システム的にはASCIIしか許容したくないことがあります。その場合に向けて、EmailStrを継承してASCIIのみ許容する拡張クラスを作ります。 環境 Python 3.12.7 Pydantic 2.9.2 実装 まずは、ASCII文字だけチェックできるように正規表現を用意します。 ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ 次のコードでEmailStrを継承しつつ、自分が追加…

  • Pythonでgroup_byしたいならdefaultdictを使う

    始めに Pythonでデータをグループ化する際、defaultdictを使用すると簡単かつ効率的に実装できます。この記事では、defaultdictを使ったgroup_byの実装方法と、itertools.groupbyとの違いについて解説します。 環境 Python 3.12.6 実装 defaultdictを使用すればシンプルに実装できます。 from collections import defaultdict class TestGroupBy: class _Test: def __init__(self, user_id, group_id): self.user_id = use…

  • 【障害】SentryのtracePropagationTargetsの指定を誤った

    Sentryの設定を軽い気持ちで変更したところ大規模障害につながってしまったので、もう忘れないようにするためのメモ。 環境 @sentry/angular-ivy 7.144.0 発生事象 S3へのファイルアップロードに失敗した。 原因 tracePropagationTargetsの指定を誤ってしまい、S3のファイルアップロード時にBaggageとSentry-Traceのリクエストヘッダが付与されてしまったため。また、S3側でAccess-Control-Allow-Headersを指定していたので、BaggageとSentry-Traceが付与されているとCORSエラーが発生して、Htt…

  • PydanticのJsonはそのまま使わないほうがいい

    始めに PydanticにはJsonという便利な型があります。便利ではあるのですが、素のJson型では開発しづらい点があったので自分のアプリケーションでは拡張して使っています。 今回の記事では何に困ったのか、どのように拡張したのかを記載します。 環境 Python 3.12.4 FastAPI 0.114.2 Pydantic 2.9.1 ユースケース フロントで自由なデータ構造を定義してバックエンドとしては単純に保存する。また、フロントで取り出せるようにバックエンドで保存したデータ構造をフロントに返却する。 困ったケース PydanticのJsonで定義するとフロントで定義した自由なデータ構…

  • SQLAlchemyで大文字小文字を区別せず比較する(lower, ilike)

    始めに email等の項目は大文字小文字を区別せずに比較したいことがあります。 その場合には小文字化して比較することになります。今回の記事では、PythonのSQLAlchemyで使用するlowerとilikeを素振りします。 環境 Python 3.12.3 SQLAlchemy 2.0.31 lower DB側で補完しているデータもlowerとするときにはfunc.lowerを使用します。渡すパラメータに関してはPythonのlowerを使用してください。 select(User).where(func.lower(User.email) == parameter.lower()) ili…

  • SQLModelで親と一緒に子テーブルを削除する(cascade_delete, ondelete)

    始めに 外部キー制約があるレコードを削除するとき、参照元テーブルよりも参照先テーブルを先に削除する必要があります。 Railsの場合、次のようにdependentに定義しておくと、Parentテーブルを削除したタイミングでChildテーブルも削除されます。 class Parent < ApplicationRecord has_one :child, dependent: :destroy end class Child < ApplicationRecord belongs_to :parent end 今回の記事では、PythonのSQLModelを使用したときに、Parentテーブルを…

  • SQLAlchemyではselectinloadを使うのが安定

    始めに 自分用メモ。sqlalchemyではeager loadをする際にsubqueryloadとselectinload等々さまざまなload方法を指定できます。 しかし、片方はdeprecatedまでは設定されていませんが、非推奨なloading方法なのでそれを忘れないようにするための記事です。 環境 Python 3.12.4 SQLAlchemy 2.0.32 実装 selectinloadの方が推奨されている。SQLAlchemyがV1のころはsubqueryloadも使用されていたが、V2になってからは非推奨な場面が増えています。 もし、複数キーで突合したい場合はselectin…

  • Pydanticではミュータブルでもdefault, default_factoryのどっちでもよさそう

    結論 pydanticではdefaultもdefault_factoryも同等の結果を返却しそう。 始めに 小ネタ記事。Pythonではデフォルト引数にミュータブルな値を指定したうえで、ミュータブルな操作を行うと、同じインスタンスを共有してしまいます。 def default_param(param: str, result:List[str]=[]) -> List[str]: result.append(param) return result _ = default_param("1") result = default_param("2") print(result) # "1"をap…

  • Pythonのenumをintで継承しなくてもIntEnumが標準化されてた

    始めに 過去にPythonのenumはint等のプリミティブ型を継承すると便利という記事を投稿していました。 その後、Python3.11にてIntEnumやStrEnumが標準化されていることを知ったので共有します。 環境 Python 3.12.4 実装 intEnumの使用方法は次のとおりです。 from enum import IntEnum class IntInheritEnum(IntEnum): ID = 1 # 列挙型ではなく、intとして振舞うため1にアクセスできる IntInheritEnum.ID # 本来のアクセス方法 IntInheritEnum.ID.value …

  • FastAPIでDIのメソッドにパラメータを渡す(同期も非同期も)

    始めに FastAPIにてメソッドやクラスをDIできますが、DI時に部分的に処理を差し替えたい時があります。その時にパラメータを渡せば処理を差し替えられますが、少々ハマったのでそれをブログにします。 環境 Python 3.12.4 FastAPI 0.112.0 実装 同期処理の場合 Dependsで呼び出す際にlambdaでパラメータを使用すれば呼び出せます。ただし、非同期処理は呼び出せないので注意してください。コンパイルエラーは発生しませんが何も起こりません。 async def async_printer(msg: str) -> None: print(msg) def printe…

  • FastAPIで任意のHttpStatusと任意の型を返却する(JSONResponse)

    始めに FastAPIではHTTPExceptionを使用すればHttpStatusを200以外でも返却可能です。しかし、エラー詳細は1つしか返却できません。ファイルのエラーハンドリングでは多数のエラーが発生した場合には、複数のエラーを返却したいユースケースがあります。 ExceptionHandlerを使用することでもHTTPStatusや複数エラーを返却するようにできますが、基本的にはファイルバリデーション処理でしか使用しないため、全体に適用するには範囲が大きすぎます。 今回の記事ではファイルのバリデーション結果を返却するために次の仕様を満たせるようにします。 バリデーションに失敗したらH…

  • PythonのPydanticでdatetimeのシリアライズフォーマットを決める

    始めに Pythonにてアプリケーション内ではdatetimeとして扱いつつ、APIとしてはYYYY-mm-dd等の特定のフォーマットの文字列で返却したいことがあります。 今回はPydanticを用いて実装する方法を記事にします。 環境 Python 3.12.4 Pydantic 2.8.2 実装 field_serializer を使用する field_serializerを用いることで、シリアライズ時にフォーマットしてくれるようになります。 次のコードでは、特に何もしていなければISO8601のフォーマットで返却し、field_serializerが有効な個所では%Y-%m-%d %H:…

  • FILTER関数で足りない行を見つける(Google スプレッドシート)

    始めに 小ネタ。 更新系処理にて1000レコードあるemailが含まれているCSVをアップロードしたときに、DB側には999レコードしかない時には1レコード足りないために処理が失敗するとします。その場合どのレコードがDBに足りないかを調査する必要があります。 今回の記事では、その足りない1レコードを調査するためにGoogle スプレッドシートのFILTER関数を使えば一発で差分を検索できる方法を知ったのでブログにします。 環境 Google スプレッドシート 20240721 時点 実装 比較したいレコードをA列、B列に記載している状態で、D3セル、E3セルに次の数式を入力します。そうすると、…

  • 【詳細不明】NoInspectionAvailable を回避する

    始めに ※ 自宅で検証した際には実装できなかったので詳細は不明です。 テスト実装中に次のエラーが発生しました。 E sqlalchemy.exc.NoInspectionAvailable: No inspection system is available for object of type <class 'models.User'> 発生原因が不明ですが、発生しないように対応できたのでその件を記事にします。 環境 Python 3.12.3 SQLAlchemy 2.0.27 発生したバージョン 2.0.31 再現できず 対応 インスタンスをcopyして対応しました。または、commit…

  • Ngrokで無料プランでドメインを固定できるようになっていた(2023/08/16 以降できたらしい)

    2023年8月16日からできるようになっていたのを、単純に知らなかったので共有するだけのブログです。 ローカルで外部からAPIを実行する検証をしたい時があります。たとえばWebhookの検証だったり、Outlook連携の検証だったり。 そのときにローカルのAPIをHTTPSで外部公開できて有用なのがNgrokでした。ただ、昔はNgrokを無料プランで使用する場合は公開されるAPIが常にランダムになり、Ngrokを検証するたびにいろんな箇所を修正する必要がありました。 ngrok http 3000 https://7a55-221-117-101-49.ngrok-free.app それが、2…

  • PythonでSoftAssersionをする(use pytest-check, avoid assertion roulette)

    自動テストの原則として、1テストに1検証とした方が良いです。これが複数あった時には失敗箇所が分かりづらくなってしまうため、その状態をバッドパターンとしてAssertion Rouletteと呼びます。 今回の記事では、PythonのTestフレームワークであるPytestを拡張しているpytest-checkを使用してAssertion Rouletteを回避するのを紹介します。 環境 Python 3.12.3 pytest-check 2.3.1 使用方法 Assertion Rouletteを回避するなら、pytest-checkを依存関係に含めてcheck.xxxメソッドを使用するだけ…

  • Pythonのpandasで月の第2営業日を求める

    始めに 各月の第2営業日に処理したいバッチ処理がありました。 PythonのpandasのCustomBusinessMonthBeginで営業日を計算できそうだったので、各月の営業日を求める方法を記載します。 環境 Python 3.12.3 holidays 0.50 pandas 2.2.2 実装 祝日と営業日について 前回の記事である程度解説しているので、前回の記事を参考にしてください。 Pythonのpandasで3営業日後を調べる - きり丸の技術日記 月最初の営業日を求める CustomBusinessMonthBeginで月の最初の営業日を求められます。今回の記事ではエイリアス…

  • Pythonのpandasで3営業日後を調べる

    Pythonで営業日換算するときにpandasの型に営業日換算できる型があったので素振りしました。 なお、個人的にpolarsというpandasよりも高速処理できるライブラリに移行しようとしていますが、polars側には今回紹介する型がないので自作する必要があります。 環境 Python 3.12.3 holidays 0.50 pandas 2.2.2 実装 祝日 日本の祝日を含めて営業日換算する必要があるので、定義する必要があります。 自分で定義してもよいのですが、今回は日本の祝日も取り扱っているライブラリのholidaysを使用します。 GitHub - vacanza/python-h…

  • SQLAlchemyで同一項目でアプリとDBの値を変更する(hybrid_property)

    例えばDBで論理削除しているユーザを画面上で表示する際に「削除済ユーザ」と表示したい。PythonのSQLAlchemyであれば、画面上の表示は「削除済ユーザ」としつつ、DBの値は元の「きり丸」としておくことが可能です。 今回の記事では、SQLAlchemyを使用してアプリ上では「削除済ユーザ」、DB上では元のまま「きり丸」とする方法を記載いたします。 なお、誤った使用をしていると意図せずエラーになってしまうので気を付けましょう。 環境 Python 3.12.3 SQLAlchemy 2.0.30 使用方法 次のようにhybrid_propertyを使用することで、アプリ上では「削除済ユーザ…

  • Pythonでswitch文を書きたい(match, パターンマッチング)

    Pythonでは3.10からパターンマッチングができるようになりました。Pythonではswitchではなく、matchで他言語のswitchと同等機能を提供できます。なお、当然ながらswitch文がない3.10以前はif... elif... elif... elseしかできないです。 環境 Python 3.12.3 リテラルマッチング 通常のリテラルマッチングができます。A or B 等のor条件は で設定できます。また、Pythonでdefaultにあたるのは_を使用します。 次の例は、環境がローカルならダミークラス、それ以外の環境なら本物のクラス、もし未定義の環境の場合はエラーとなる…

  • MissingGreenletが起きたときの対応

    処理高速化のためにSQLAlchemyを非同期処理で使用していると、気を付けないとMissingGreenletというエラーが発生します。その対策をブログにします。 環境 Python 3.12.3 sqlalchemy 2.0.30 ゴール AsyncSessionを使用している最中に、次のエラーが出たときの対応を記載する。 sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected pla…

  • 【Git】マージ済みのリモートブランチをローカルブランチから削除する

    Gitでブランチを切って開発しているとローカルブランチはすぐに複数増えてしまいます。今回の記事では、リモートリポジトリが存在しない場合にローカルブランチもワンライナーで削除するためのメモ。 環境 Git 2.34.1 WSL Ubuntu 22.04.4 LTS ゴール マージや削除されたリモートリポジトリがある場合、ローカルのリポジトリも削除するのをワンライナーで行う。 コマンド # マージ済(ローカル修正がない場合)のみ削除 git fetch --prune && git branch -vv grep 'gone]' awk '{print $1}' xargs git b…

  • FastAPIのHTTPExcrptionはログに出しても空文字列の可能性がある

    FastAPIでHTTPExceptionをログに出力しようとした時のメモ。 環境 Python 3.12.3 FastAPI 0.103.1 0.110.0 対応 少し古いFastAPIのライブラリなら、reprを使用してシリアライズしてください。もし、strで検証しても空文字列でなければ、そのままでも問題ありません。 from fastapi import HTTPException exc = HTTPException(status_code=404, detail='NOT_FOUND') print(exc) # '' # 空文字列の可能性がある # 404: NOT_FOUND …

  • Pythonのjinja2でマルチパートメールのテンプレートを取得する

    Pythonでマルチパートメールを送る方法をブログにしました。しかし、前回の記事はファイルからテンプレートを取得していないので、マルチパートメールを実質運用できません。今回はjinja2を使用してファイルからテンプレートを取得することで実運用できるようにします。 環境 Python 3.12.3 jinja2 3.1.3 MailHog v1.0.1 事前条件 前回記事をベースに、jinja2でファイルのテンプレートを取得できるようにする。 https://nainaistar.hatenablog.com/entry/multipart-mail-in-python-by-smtplib#t…

  • Pythonでマルチパートメールを送る(smtplib)

    Pythonでメールを送る方法を素振りしたかったのでメモします。SMTPを使用し、マルチパートメールを送るところまでを目標とします。 なお、実務ではSESを使用したり、SendGridを使用することが多いと思うので、あくまでローカルでメールの動作確認をする程度しか使用できません。 環境 Python 3.12.2 MailHog v1.0.1 事前条件 MailHogを利用して、SMTPを受け取るメールテストサーバを立てます。 mail: image: mailhog/mailhog:latest ports: - 8025:8025 # WebUI - 1025:1025 # SMTP 対応…

  • GitHubでDraftのPRを除外してOpenだけにしたい

    GitHubでレビューを依頼されたときに、レビュー依頼が多すぎてOpen状態のPullRequestだけを確認したい時のメモ。 環境 GitHub 2024/04/20 対応 次のどちらかをフィルタに設定してください。 draft:false -is:draft ちなみに、JetBrainsのPull Requestsでも有効です。 終わりに 作業開始したらDraftでレビュー依頼を先に出すルールで仕事しているので、本当にレビューしたらよい対象をみつけるのがたいへんでした。 フィルタに-を付けたらNotの意味になることも分かったので、今後は地味に作業改善ができます。 参考情報 https://…

  • DockerのMinioをアップデートしたら起動しなくなった

    DockerのMinioを使用していますが、イメージが古すぎてディレクトリごとアップロードができませんでした。そのため、最新イメージにアップデートしようとしたところ、エラーメッセージが出て起動しなかったその対応を記載します。 ※ プロダクション環境でMinioを使用している場合には適用できません。 環境 Docker Minio RELEASE.2019-01-31T00-31-19Z RELEASE.2024-02-13T15-35-11Z ゴール 次のエラーメッセージが出たときに、最新イメージで起動できるようにする。 ERROR Unable to use the drive /data:…

  • WSLで起動したサーバにiPhone等のモバイル端末からアクセスする

    ※ 家で検証したときはできなかったのですが、会社で検証したときはできましたので、残しておきます。 WSLで起動したサーバに対してiPhoneやAndroidからアクセスすることでモバイル端末の実機確認をしたかったのですが、単純にWSLのIPにアクセスするだけでは確認できなかったので手順を残します。 環境 WSL Ubuntu 22.04.4 LTS ゴール iPhoneでWSL上に起動しているサーバにアクセスする。 詳細 管理者権限でコマンドプロンプトを起動します 管理者権限でコマンドプロンプトを起動します。私の過去記事に簡単に管理者権限でアプリケーションを起動する方法を残しているので、参考に…

  • Gmailでテキストメールを受信して確認する(クライアント問わない方法)

    Gmailでテキストメールを送信する方法はたくさん見つかったのですが、受信してテキストメールを確認する方法は見つからなかったのでブログにします。 なお、GmailではHTMLメールとテキストメールを選んで受信はできません。そのため、受信するではなく、受信してテキストメールを確認するが本題です。 環境 Gmail 20240320時点 確認方法 テキストメールを確認したいメールのソースを確認する 確認したいメールを開き、「︙」をクリックしてメッセージのソースを確認を選択します。 デコードしてテキストメールを確認する メッセージのソースからテキストメールの箇所を探します。text/plainのブロ…

  • testcontainers-pythonでMinioを扱う

    testcontainers-pythonでminioを使う際に少々手間どったのでメモに残します。 なお、この記事ではtestcontainers自体のメリット等については記載いたしません。 環境 Python 3.12 boto3 1.34.69 minio 7.2.5 testcontainers 4.1.1 ゴール boto3でminioに対してファイルアップロードできたことを検証します。minioについてはtestcontainersでセットアップします。 下準備 testcontainersとminioをdevDependenciesに加えます。各々のパッケージマネジャで読み替えてく…

  • 【Scrap】pytestについて

    ZennのScrapsと同じような感覚の記事。間違っている可能性は十分にあります。 今回の記事ではpytestについて自分が調べたことをまとめます。 環境 Python 3.7.9 pytest 7.4.3 pytest-check 2.2.2 Pytestについて 処理順番 pytestではヒットした順番で順次テストするのではなく、collectionというテスト対象のメソッドを集めた過程を経てテストを実行します。この実行前のcollectionで先頭にTestが付いているクラス、test_がついているメソッドを探しています。感覚的には、200テストを探すのに1秒くらいかかるので、テストケー…

  • Pythonのclassは暗黙的にobjectを継承している(reportMissingSuperCallの対応)

    pyrightを使用している際に、reportMissingSuperCallが発生したので対応していました。 error: Method "__init__" does not call the method of the same name in parent class (reportMissingSuperCall) ただし、コード上は特に何も継承していません。 class Hoge: def __init__(self, name: str): self.name = name このエラーメッセージを対応するために調査した内容をメモします。 環境 Python 3.12 原因 掲題の…

  • 同じJSONやDictでも生成されるJWTは変わることがある(Pythonで例示)

    同一のJSONやDictを与えているはずなのに、生成されたJWTが変わってしまったというメモ。 なお、ライブラリの特性である可能性はあるので、すべてのJWTライブラリで発生するわけではありません。 環境 Python 3.11 python-jose 3.3.0 原因 JSONやDictとしては等価だったが、JSONを文字列化(シリアライズ)したタイミングでキーの順番が変わってしまったため。シリアライズした結果を元にencodeするので、生成されるJWTが等価にならない。 事象発生時のシリアライズ {"id": 1, "exp": 1710152710, "iss": "kirimaru"} …

  • テストのメールドメインはexamle.comのほかにもある(RFC 2606)

    テスト時に使用するメールドメインについてexample.comを使用していますが、メールドメインで制御しているコードを検証したい時にほかにも安全に使えるドメインがないかを調べたときのメモ。 すでに飽和している情報ですが自分のメモのために残します。 テストで使えるトップレベルドメイン RFC 2606 RFC 2606で定義されているものは次の4つです。 .test .example .invalid .localhost 使い分けについては、RFC 2606で提案されています。 https://datatracker.ietf.org/doc/html/rfc2606 IANA(ICANN) …

  • Pythonのエラーチェイン(例外を元に例外を投げる)には3種類あるがあまり気にしなくていい

    Pythonでフレームワークから発生した例外を元に、適切に自作した例外に変換する方法に複数あることを知ったので、それを素振りしました。 なお、結果だけ先にお伝えするとraiseするだけでも9割問題ありません。 環境 Python 3.11.6 確認方法 Pythonでは単純にエラーをraiseするだけでなく、from eとfrom Noneという構文を付けてraiseすることもできます。 try: try: 1 / 0 except ZeroDivisionError as e: raise ValueError("ERROR") # 1つ目 raise ValueError("ERROR")…

  • Gitにchmodした結果を含めない、そして復帰させた時の手順(core.fileMode)

    WSLで開発中にroot権限で作成されたファイルがあり、IntelliJ IDEAで更新できなかったファイルがありました。そのためディレクトリごとchownとchmodを行ったのですが、Gitに変更箇所があると検知されてしまい、気づかずにコミットしてしまいました。 今回の記事では、chmodを行っても検知されないようにする設定方法と誤ってコミットしてしまったときの復帰手順の操作を記載します。復帰手順に関しては、もっといいやり方がありそうですので、もし同じ事象にハマったら教えてください。 環境 Git 2.34.1 IntelliJ IDEA 2024.1 EAP 設定方法 次のコマンドを実行す…

  • RailsのRSpecテストを並列化して30分から12分に短縮した(parallel_testsと性能アップ)

    CI上のRailsのRSpecテストが30分もかかっていてストレスフルだったので、テストを並列化する等で30分かかっていた時間を12分まで削減しました。 そのときのメモ。 環境 AWS CodeBuild Ruby 2.7.2 Rails 6.0.3.6 Parallel_tests 4.4.0 MySQL 8 前提 docker composeでテストは閉じている。そのため、RDS等のアクセスは発生していない。 対応 parallel_testsライブラリを入れる 並列化ライブラリのparallel_testsを導入します。 group :development, :test do gem …

  • WSLのIPを調べる(WSLで起動したサーバに他端末からアクセスしたい)

    同一ネットワークに所属していればローカルで起動したサーバをiPhone等の他端末からアクセスできるのは知っています。Windowsの場合ipconfigで表示されたIPを指定すればアクセスできることも知っています。ただ、WSLで起動したサーバに対してはアクセスできなかったので、それを回避するためのメモ。 環境 Ubuntu 22.04.2 LTS GNU/Linux 5.15.133.1-microsoft-standard-WSL2 x86_64 前提条件 なし コマンド 次のコマンドで得られたIPを指定すればアクセスできます。 ip addr show eth0 grep inet …

  • WSLの時刻がズレたのでWindowsの時刻に修正する(sudo hwclock -s)

    WSLの時刻がズレたことによるエラーが発生したので、時刻修正をした時のメモ。 環境 Ubuntu 22.04.2 LTS GNU/Linux 5.15.133.1-microsoft-standard-WSL2 x86_64 前提条件 なし コマンド 次のコマンドをWSL上で実行することで、Windowsの時刻と一致できます。 sudo hwclock --hctosys または sudo hwclock -s 説明 WSLからWindowsのハードウェアクロック側にアクセスするので、sudo hwclockが必要です。 そのオプションとしてソフトウェアクロックをハードウェアクロックの値で更新…

  • WSLの一般ユーザのパスワードをリセットしたい

    sudoコマンドを実行したいが、パスワードを忘れたのでWSLのパスワードをリセットするときのメモ。 環境 Ubuntu 22.04.2 LTS GNU/Linux 5.15.133.1-microsoft-standard-WSL2 x86_64 前提条件 変更対象の一般ユーザー名が分かっていること コマンド # root ユーザでログインする wsl -u root # kirimaruユーザのパスワード変更 passwd kirimaru ソースコード なし 終わりに WSL上ではなく、Windows上で構築することに慣れてしまっているので忘れてました。 小ネタですが、残しておきます。

  • WindowsのGit操作で発生したFilename too longを解決する(git config --global core.longpaths true)

    Macを使用している他人がコミットしたファイルをpullしようとしたらFilename too longが出力されてpullできませんでした。その解決方法を残します。 環境 Windows 11 GitBash 4.4.23(1)-release ゴール 次の操作時にエラーが発生しない。 $ git reset --hard origin/develop error: unable to create file xxx/yyy/zzz[ファイルパス] :Filename too long 解決方法 Gitのcore.longpathsをtrueに設定する。 git config --globa…

  • SQLで同姓同名が何人・何種類あるかを知りたい(重複レコードの存在とどのレコードかを知りたい)

    SQLの小ネタ。 レコードが1:Nの関係のときに、Nが一定数以上のレコードが存在しうるか、存在する場合はどのようなレコードかを知りたいことがありました。 今回の記事ではユースケースとして分かりやすいように、usersテーブルからnameのうち同姓同名が何人・何種類あるかを調べることができるのをゴールとします。 環境 MySQL 8 下準備 次のテーブルを用意する。 CREATE TABLE `users` ( `id` int NOT NULL, `name` varchar(1024), ) INSERT INTO users (id, name) VALUES (1, 'あいうえお'); …

  • FastAPIのpydanticの422UnprocessableEntityはExceptionのExceptionHandlerではキャッチできない

    FastAPIで意図しないエラーが発生したときにExceptionでハンドリングしていましたが、それだけではpydanticで発生するエラーがキャッチできなかったのでメモします。 なお、pydanticはAPIのRequestとResponseのモデルで使用していますので、フロントのバリデーションエラーと考えてください。 環境 Python 3.11 FastAPI 0.105.0 pydantic 2.5.3 ゴール pydanticで発生していた次の詳細すぎるメッセージが返却されないこと。 { "detail": [ { "type": "greater_than_equal", "loc…

  • AnyIOのテストをasyncioだけで動かす(asyncioとtrioの2倍動かないようにする)

    AnyIOを使用しているテストで、意図せずにasyncioとtrioの2つで動いてしまったテストがあったので、asyncioだけにした時のメモ。 環境 Python 3.11 AnyIO 3.7.1 Pytest 7.4.3 実装 conftest.pyに次の処理を入れると、asyncioだけが動きます。 @pytest.fixture def anyio_backend(): return 'asyncio' テストをAnyIOで動かすには 次のどちらかで動きます。 # 先頭で宣言する pytestmark = pytest.mark.anyio # または、メソッドごとに定義する @pyt…

  • SQLで条件が一致しないレコードを特定する(NOT EXISTS)

    小ネタ。 特定の条件に一致するレコードを取得するのはINNER JOIN等を使う方法は知ってましたが、一致しないレコードを取得する方法を知らなかったのでメモします。 環境 MySQL 8 実装 NOT EXISTSを使えば条件一致しないレコードを特定できます。逆に条件一致するレコードを調べるときはEXISTSを使えば特定できます。 SELECT * FROM users WHERE NOT EXISTS(SELECT 1 FROM user_profiles WHERE users.id = user_profiles.id) 検証方法 USERSテーブルとUSER_PROFILESテーブルを…

  • Pythonのenumはint等のプリミティブ型を継承すると便利

    基本的には推奨されない書き方のようですが、使ってみて便利だったのでメモします。 環境 Python 3.12 実装 int等のプリミティブな型の継承は次のとおりです。 from enum import Enum class IntInheritEnum(int, Enum): ID = 1 # 列挙型ではなく、intとして振舞うため1にアクセスできる IntInheritEnum.ID # 本来のアクセス方法 IntInheritEnum.ID.value ただし、自作クラス等は継承できません。metaclassの競合が起きるため、クラスで定義したかったものがあれば、namedtuple等を使…

  • Pythonの__iter__を素振りする(First Class Collection[FCC]で使えるかも)

    Pythonではイテレータを簡単に作れます。もしかしたら何かに使えるかもしれないので、素振りします。 環境 Python 3.12 ゴール PythonのFCC(First Class Collection)にて、For文を使用する際にFCCのインスタンスのまま使用できること。 from typing import List class User(): # ... 省略 class Users(): value: List[User] # コンストラクタ省略 users = Users([]) # この記載ができることがゴール [user for user in users] # ※ もちろん…

  • Gmailで1度検索したメールをURLで開きたい(メールのID知りたい)

    Gmailで1度開いたメールを後でURLで開けるようにする方法を自分用にメモします。特に件名を検索した後に、該当のメールをURLを開く方法を知りたかった記事です。 環境 Gmail 2023/11/18時点 IDの取得方法 URLのサブディレクトリの最後がメールのIDを示しています。 https://mail.google.com/mail/u/0/#search/github/FMfcgzGwHfpLhNbfcnNVXsHPlLbmWplg 今回の場合、最後のFMfcgzGwHfpLhNbfcnNVXsHPlLbmWplgが必要です。 開けるメールにする フラグメントをinboxかallにし…

  • Pythonのデフォルト引数では配列ではなくNoneを使わないとダメ(ミュータブルはNG)

    有名な話ですがハマったのでブログにします。 環境 Python 3.9 事象 Pythonでデフォルト引数に配列を定義すると、意図せずに同じインスタンスを使用してしまう。 def target_1(value, list=[]): list.append(value) return list def test_01(): a = target_1("1") # ["1"] assert len(a) == 1 b = target_1("2") # a, b 両方とも次の値になる # ["1", "2"] assert len(a) == 2 assert len(b) == 2 # インスタ…

  • JSONPathから対象のJSONの行にフォーカスをあてる(IntelliJ IDEAのプラグインのJSON Key Finderを使用)

    JSONからJSONPathを取得する方法を記事にしたことで、開発中のファイルに作成したJSONPathを定義できるようになりました。 今回の記事では、逆にJSONPathは分かっていI18nの定義ファイルのどこで定義してあるかを知れます。 環境 IntelliJ IDEA 2023.2 JSON Key Finder 対応 プラグインのJSON Key Finderを使用すると、JSONPathでの検索ができて、フォーカスをあてられます。 プラグインのインストール 次のプラグインをインストールします。 JSON Key Finder JSON Pathでの検索 プラグインをインストールした後…

  • OldstarのHDMI 変換アダプタで表示できない場合の対応(Win11の場合)

    この記事ではOldstarのHDMI変換アダプタをWin11でも表示させる方法をブログにします。同梱されているドライバはWin10までしか対応していません。 なおWin11で表示はできるものの、10月23日時点ではドライバの品質が悪く、使用に耐えられない描画遅延が発生しているので返品しました。 対象商品 https://www.amazon.co.jp/gp/product/B0CJ2KFHXC 対応 同梱されているドライバではなく、公式ページの最新ドライバを使用してください。まだ英語対応されていないのか、中国語のインストーラが起動します。 http://www.ultrasemi.com/u…

  • Javaでメルセンヌ数を求める

    Javaでメルセンヌ数(2の冪-1)を求める方法を記載します。 メルセンヌ数についてはWikipediaを参考にしてください。 前提 Java 21 対応 2の冪-1が整数となる値を求めるために次の式を使用します。 private static boolean isMersenne(int value) { return log2(value + 1) % 1 == 0; } public static double log2(int value) { return Math.log(value) / Math.log(2); } 解説 2の冪-1 = メルセンヌ数ですので、式変形して2の冪=…

  • Javaで二進対数(log2x)を求める

    Javaで用意されているMathクラスだと十進対数(logx)だけしかないので二進対数(log2x)で計算する方法をメモします。 前提 Java 21 対応 十進対数から二進対数を割るだけです。 public static double log2(int value) { return Math.log(value) / Math.log(2); } ソースコード https://github.com/hirotoKirimaru/cucumber-sample/blob/c32978ce459ead32f54683830851e3d110f68fe9/kirimaru-core/src/te…

  • 【Bash】別ファイルに定義した変数を使用する

    小ネタ。なお、特に説明はしていませんが、関数も変数と同じように使えます。 環境 Bash GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu) Ubuntu 20.04.2 LTS GitHub Codespaces 概要 変数を使用したいシェルからsourceコマンドで変数を定義したシェルを呼びます 対応 変数を使用したいシェル sourceコマンドで変数を定義しているファイルを呼びます。 ファイル名:main.sh #!/bin/bash # 変数を定義しているシェルを呼ぶ source ./property/it.sh ech…

  • Excelで保存時にA1セルに保存する(VBAマクロ使用)

    Excelは保存時に強調したいセルがある、等々の理由がない限りA1セルに合わせる、というマナーがあります。そのマナーの是非について問うつもりはありません。 今回の記事では、保存時に自動でA1セルに合わせるマクロを記載します。 前提 Excel Microsoft Office Home And Business 2019 対応 概要 全シートをA1セルに合わせるメソッドを定義 保存時に起動するイベントプロシージャを定義 全シートをA1セルに合わせるメソッドを定義 ThisWorkbook.Worksheetsを呼ぶとシートの数分だけループ処理が走ります。 あとは全シートをA1セルに合わせるため…

  • IntelliJ IDEAで目的のJSONパスを取得する

    JSONでI18n対応していると、目的の文言を出力する時にJSONパスが必要です。深い構造ほどパスの把握に時間がかかります。 VS Code, IntelliJ IDEAのIDEでJSONの目的のパスにフォーカスしていると、画面の上部や下部にJSONパスが表示されます。それを手打ちしてコピーしていたのですが、IntelliJ IDEAの機能でJSONパスを一発で取得できる方法がわかったので記事に残します。 前提 IntelliJ IDEA 2023.2.2 対応 目的のパスにフォーカスしている状態で、右クリックしてCopyをしたらJSONパスを取得できます。 # Copy Reference …

  • Pythonで配列から特定のキーだけで検索したい時は辞書型を経由すると速い

    当たり前の話ではありますが。 Userクラスの配列からuser_idをキーに検索したい、emailをキーに検索したい等々の特定のキーがある場合、辞書型を経由すると非常に早く値を取得できます。 前提 Python 3.9 対応 配列を辞書型に変換する 最初にUserクラスを定義します。 class User: def __init__(self, user_id): self.user_id = user_id user_id: str 作成したUserクラスを元にuser_idをkeyとして、valueがUserクラスの辞書型を作成します。 # ユーザ配列の作成 users = [User(u…

  • 001等の左0埋めのコード値を使うのはやめよう。それは8進数と判断される可能性がある

    小ネタ。 前提 なし 詳細 私が関わっているシステムでは、001, 002等で種類を表すコード値を使っていることがあります。基本的には文字列で処理するので問題はほとんど発生しないのですが、状況によっては8進数の文字列と解釈されることがあります。可能な限りE001, I001等のprefixを付与するか、0埋めのコード値を使うことを回避してください。 参考 各進数表現のフォーマットを記載します。 8進数は言語によってフォーマットが異なるので注意してください。 2進数 0bを先頭に付与する 0b01 8進数 0を先頭に付与する 07 C言語やC++言語、Java、JavaScript(ES5以前)…

  • Excelで縦回転するマウスホイールで横スクロールしたい

    小ネタ。 横スクロールできるホイール(チルトホイール)がマウスについていたら嬉しいのですが、無いマウスを使用することもあるので備忘録として。 前提 Excel Microsoft Office Home And Business 2019 Windows Mac 未確認 方法 Shift + Ctrl + 縦スクロールで横スクロールができる。 Macの場合はShift + 縦スクロールで横スクロールができるようですが、私の環境では動作確認していません。 終わりに Twitterで見かけたので、自分用のメモとして残します。 参考情報 後輩君「え、横にも動けるチルトホイールのマウス勧めたのに買わな…

  • EXCELで最新のデータ(一番下、一番右)だけを参照する(数式とINDIRECT)

    地味に毎回調べるのでメモ。 環境 Microsoft Office Home and Business 2019 Microsoft® Excel® 2019 MSO (16.0.14228.20216) 64 ビット ゴール 1月から12月のデータを入力する項目があります。現在入力している最新の月(一番下、一番右)のデータだけを参照します。 前提として、歯抜けデータは存在しない。 行対応 まず、データ数を取得します。セルに値が入力されている場合、入力されたセル数を返却するCOUNTA()を使用します。画像の状態だと8を返却します。 次に一番下のセル番地を取得します。画像で入力されている中で最…

  • ソフトウェア工数見積で意識すべきABPとHPとパーキンソンの法則(CCPMの文脈)

    よくABPとHPの正式名称を忘れるので自分用にまとめます。 前提 クリティカルチェーン・プロジェクトマネジメント 略称はCCPM ABPとは ABPとはAggressive But Possibleの略称です。日本語訳としては「積極的に行えば可能」「頑張れば可能」です。私の感覚では、バッファを積まずに7割くらいの確率で達成できる時間を指してます。 HPとは HPとはHighly Possibleの略称です。日本語訳としては「だいたい可能」です。私の感覚では、バッファを積んで9.5割くらいの確率で達成できる時間を指してます。 パーキンソンの法則とは パーキンソンの法則とは仕事の量は完成のために与…

  • ブログのURLをChatGPTに考えてもらっている【ChatGPT有効活用】

    小ネタ。 タイトルとおりの記事でそれ以上の感想はありません。 前提 ChatGPT 3.5 20230813時点 経緯 最初の頃は、はてなブログ標準機能のURLを使用していました。 ただそれだとGoogle Analyticsで人気のページを確認する際に、何の記事か分かりませんでした。次に日本語URLにしたのですが、URLエンコーディングの結果よくわからない文言になってしまいました。 最後に英語URLに変更しています。英語URLだとエンコーディングが入らない分、ちゃんと理解できる文章になります。ただ、英語が得意ではないため、ブログ書いた後にタイトルを決定するのに地味に時間がかかっていたのですが…

  • Javaのtransientで本来は関わりのないデータであることを強調する

    本来の使い方とは異なります。黙って使うと怒られるかもしれないので、導入の際は念のため確認してください。 Javaにはtransientという修飾子があります。これを使うことでコードで表現できることが増えます。 環境 Java 15 ユースケース コードの表現力を増やす 関係がないデータであることを表現する Transientとは Transientは、和名で一時的という意味を持ちます。 この意味から私は「処理のために一時的に持たせた値」であることを、表現しています。 本来のTransientの役割 transientがついているフィールドをシリアライズの対象から外します。 シリアライズとはデー…

  • SpringBootの@Valueではstatic変数には設定できない(設定ファイルの値をstatic変数に設定できるようにする)

    SpringBootの@Valueを使用すると、設定ファイルの値を取得して変数に設定できます。しかし、static変数に関しては直接的に@Valueで設定できません。 今回の記事では、設定ファイルの値をstatic変数にも設定できるようにします。 前提 org.springframework.boot 2.7.0 lombok 対応 static変数でなければ、@Valueは動きます。そのため、コンストラクタで@Valueし、コンストラクタでstatic変数に設定できます。 直接取得 @SpringJUnitConfig @TestPropertySource(properties = {"d…

  • SpringBootの@Valueではstatic変数には設定できない(設定ファイルの値をstatic変数に設定できるようにする)

    SpringBootの@Valueを使用すると、設定ファイルの値を取得して変数に設定できます。しかし、static変数に関しては直接的に@Valueで設定できません。 今回の記事では、設定ファイルの値をstatic変数にも設定できるようにします。 前提 org.springframework.boot 2.7.0 lombok 対応 static変数でなければ、@Valueは動きます。そのため、コンストラクタで@Valueし、コンストラクタでstatic変数に設定できます。 直接取得 @SpringJUnitConfig @TestPropertySource(properties = {"d…

  • Javaでpropertiesファイルを読み込む

    SpringBoot等のフレームワークの機能を使用すると、簡単に設定ファイルが読み込めるようになりました。 しかし、E2Eの試験をするだけのプロジェクト等では重くなりがちなフレームワークを導入したくありません。 今回の記事では、Javaのみでpropertiesファイルを読み込む方法を記載します。なお、調べれば簡単に出る内容ではありますので、新規性はありません。 環境 Java 15 Gradle ゴール Javaで設定ファイルのpropertiesを読み込む。ymlファイルは対象外。 方法 propertiesファイルを用意する resourcesディレクトリの配下にpropertiesファ…

  • SQLAlchemyでwhere条件を変数化し、動的に変数に条件を追加する(1でも、2でも使えるはず)

    ※ 一部再現しきれていないので、誤っている可能性があります。 前提 SQLAlchemy 2.0.11 ソースコードありません 1.4.32 対応 次のどちらかで対応できます。 配列にand_インスタンスを設定し、最後に*で展開する ※ 2.0.11, 1.4.32でも確認できています。 criteria = [] criteria.append(and_(User.name == 1)) criteria.append(and_(User.email == "1@example.com")) criteria.append(and_(User.age == 30)) (await db.ex…

  • Railsでfirstを指定しているのにたまに11件取得していた(原因不明)

    当記事は問題解決に向けた記事ではありません。調べても原因が分からなかったので、事象の報告記事となります。 環境 Ruby 2.7.2 Rails 6.0.0 発生事象 ActiveRecord::Baseを継承したクラスにて、特定の条件のレコードの1行目を取得したかったので、次のようにfirstメソッドを使用していました。 User::Address.where(postCode: "1112222").first module User class Address < ActiveRecord::Base end end ただし、なぜか実行するタイミングによっては、どちらかのSQLが発行され…

  • Javaの自作アノテーションのプロパティの値を取得する(ConstraintValidator)

    以前、Javaの自作アノテーションを作成する方法をブログにしました。しかし、自作アノテーションに定義した変数を取り出して、バリデーションを行う方法がちょっとだけ面倒だったので、ブログに残します。 環境 Java 17 前提 テストする方法は、こちらの記事を参考にしてください。 ユースケース 文字数バリデーションをかけたい 今回の例では、バイト数と文字数のチェックをかけるアノテーションを付与します。 // 30バイト、10文字まで許容 @AppStringValid(byteCount = 30, wordCount = 10) private String targetStr; 対応 アノテー…

  • Javaで特定の文字数まで0埋めや任意の文字で埋めたい(padLeft, padRightのような動き)

    小ネタ。 環境 Java 17 対応 java.lang.Stringを使用します。内部的にはjava.util.Formatterを使用しています。 intの場合は%0{特定の文字数}d。Stringの場合は%{特定の文字数}sで半角スペースで左埋めしたあと、replace(半角スペース, 任意の文字)で半角スペースを任意の文字に書き換えます。 // 次の書き方は全て、1を0左埋めして001に書き換わります // intを渡す場合 String.format("%03d", 1); // Java15以降でできる書き方 "%03d".formatted(1); // Stringを渡す場合(…

  • IntelliJ IDEAのデフォルトTerminalを変更する

    公式ヘルプ読めば一発のお話。 ターミナルに強いこだわりはないのですが、ターミナルだとlsを無意識に打ってしまう癖があるので、エラーが起きないようにIntelliJ IDEAのデフォルトターミナルをGit Bashに変更しました。 その手順を残します。 環境 IntelliJ IDEA 2021.2.3 Windows 設定方法 Ctrl + Alt + SでSettingsを開きます。 Tools > Terminalを開きます。 Application SettingsのShell pathを変更します。 なお、IntelliJ IDEAは頭がいいので、プルダウンを選択するだけで終わりました…

  • Lombokの自動生成コードのsetterにブレークポイントを張って容易にデバッグしたい

    小ネタ。特定項目が処理の開始時は1だったのに、処理の終了時には1000が代入されていたとします。規模が小さいうちはSetterやBuilder等々の呼び出し元にブレークポイントを張っていればいいのですが、規模が大きくなってくるとブレークポイントを張るだけでも一苦労です。 今回の記事では、Lombokの自動生成コードにブレークポイントを張って、容易にデバッグできるようにします。 環境 Java 17 Lombok 1.18.24 デコンパイルできる環境 IntelliJ IDEA 2022.2.3 FernFlower decompiler 対応 Lombokは生成先のメソッドが存在する場合には…

  • JJUG CCC 2023 Springに20分枠で登壇したレポート

    5-10分枠のLTで登壇することはそれなりに重ねてきましたが、カンファレンスに登壇したことがなかったので思い切って登壇してきました。その登壇した自分語りですので、他の方の発表については特にこの記事では言及しません。 JJUG CCCとは 日本Javaユーザーグループ(JJUG)は、Java技術の向上・発展、開発者の支援を目的とした任意団体です。その団体が年に2回、春と秋に行うカンファレンスです。 ここ最近はコロナ禍だったので、オンラインでのカンファレンスが多かったのですが、今回はハイブリッドでの開催でした。現地参加・ビデオ参加・リモート参加を選べて、私はリモート参加していました。 発表内容 J…

arrow_drop_down

ブログリーダー」を活用して、きり丸さんをフォローしませんか?

ハンドル名
きり丸さん
ブログタイトル
きり丸の技術日記
フォロー
きり丸の技術日記

にほんブログ村 カテゴリー一覧

商用