きり丸の技術日記

技術検証したり、資格等をここに残していきます。

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:8000/tasks' 
#  -H 'accept: application/json' 
#  -H 'Content-Type: application/json' 
#  -d '{
#  "title": "クリーニングを取りに行く"
#}'
POST http://localhost:8000/tasks
accept: application/json
Content-Type: application/json

{
  "title": "クリーニングを取りに行く"
}

ファイルアップロード等のアップロードもパスさえ合っていれば同じように実行できます。

curl -X 'PUT'
  'http://localhost:8000/users/files'
  -H 'accept: application/json'
  -H 'Content-Type: multipart/form-data'
  -F 'file=@001.png;type=image/png'
# curl -X 'PUT'
#  'http://localhost:8000/users/files'
#  -H 'accept: application/json'
#  -H 'Content-Type: multipart/form-data'
#  -F 'file=@001.png;type=image/png'
POST http://localhost:8000/users/files
accept: application/json
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="001.png"

< 001.png
--WebAppBoundary--

終わりに

個人的にはRequest BodyをJSONで扱えるhttpファイルのほうが便利なのですが他の開発者に向けた手順書として実行する場合にはcURLの方が展開しやすいです。

今まで手順書としてはcURLで残しておいて、自分の検証用としてはhttpファイルで残していたのですが、cURLだけ残せばすぐに再現できるようになったのは非常に大きいメリットです。こういう地味な開発生産性に効くことをしてくれるから、JetBrains IDEは辞められませんね。

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

始めに

現在、私は複数のプロジェクトに参画していて、保守作業する際には接続先をプロジェクトごとに切り替える必要があるのですが、すべて接続先をフラットに管理していました。接続先名で無理やりprefixを付与して管理していたのですがDataGripにはフォルダのように管理できる方法があると聞いてその方法をメモします。

なお、DataGripでしか無理、と思っていたのですが他のIDEでも同様の挙動を実装できそうです。

環境

  • PyCharm Professtional
    • 2024.03
  • DataGrip
    • 2024.03.2

実装

Database explorerにて、右クリックするとMove to Folderがあります。こちらをクリックすると、フォルダを作成できます。また、名称に/を入力するとフォルダを区切れるので多層構造も可能です。

私は最近この機能を知ったのでちゃんと有効活用はできていないのですが、次のようなフォルダ構造で使用する予定です。

- {システム名}
    - localhost
    - Remote
        - 検証環境全般
    - Prod
        - 本番環境

ソースコード

なし。

終わりに

A5m2では接続先名を/で区切ると自動でフォルダ管理できたので同じような機能があると思っていたのですが、DataGripでは明示的にフォルダを作成する必要があるのですね。

まだ知らないDataGripの機能はたくさんあると思うので、細かいところまで使いこなしていきたいです。

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

始めに

レコードの有効期間を表示したいときに、start_at, end_atのカラムを用いて表現していました。そして、end_atがnullの場合にアクティブなレコードとして表現しようとしていました。しかし、このやり方ではデータの管理方法に失敗するとアクティブなレコードが複数できてしまう可能性があります。

そのため、アクティブなレコードを1つだけに絞りたかったので、別の主キー + end_atでアクティブなレコードであること表現しようとしました。

しかし、その方法がうまくいかなかったので、同じ轍を踏まないようにブログに残しておきます。

環境

  • MySQL
    • 8.0
  • PostgreSQL
    • 17.2

前提

ユーザー間の関係を表現するために、user_id_1, user_id_2start_at, end_atで有効期間を表示するテーブルです。

  • user_id_1
  • user_id_2

さらに、アクティブなレコードは1つにしたいです。画像のようなレコードが生まれることを期待しています。

うまくいかない原因

DBにおいてnullは「存在しない値」ではありません。nullは「不明」な値です。そのため、nullをもとにハンドリングしようとしてもAレコードのnullとBレコードのnullは一致していると判断されず、nullを使用するとアクティブレコードが1つだけという判定ができません。

実装

PostgreSQLの場合

nullの場合に一意制約を作用させる書き方ができるので、次のように書いてください。

CREATE TABLE relation_timelines (
    id SERIAL PRIMARY KEY,
    user_id_1 INTEGER,
    user_id_2 INTEGER,
    start_at TIMESTAMP,
    end_at TIMESTAMP,
    CONSTRAINT uq_user_ids_start_end UNIQUE (user_id_1, user_id_2, start_at, end_at)
);

CREATE UNIQUE INDEX idx_relation_timelines_unique
ON relation_timelines (user_id_1, user_id_2, (end_at IS NULL))
WHERE end_at IS NULL;

MySQLの場合

MySQLの場合はUNIQUEにするための仮想カラムを追加してください。注意点としては、仮想カラムを0にすると有効なレコード、無効なレコードを1つずつしか許容しないので注意してください。

create table relation_timelines
(
    id          int auto_increment primary key,
    user_id_1   int      null,
    user_id_2   int      null,
    start_at    datetime null,
    end_at      datetime null,
    end_at_flag tinyint as (if((`end_at` is null), 1, NULL)),
    constraint uq_user_ids_start_end
        unique (user_id_1, user_id_2, start_at, end_at),
    constraint uq_user_ids_start_end_flag
        unique (user_id_1, user_id_2, end_at_flag)
);

ソースコード

  • なし

終わりに

nullが不明な値であることを今回の失敗で気付けました。MySQLの場合には仮想カラムを使用する一手間があるので、ちょっとたいへんですね。

参考情報