7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

go言語のORMとしてentを使ってみた

Last updated at Posted at 2025-11-30

開発本部でエンジニアをしている押久保です。
今回、ORM ライブラリとして ent を採用しました。実際どのように使っているかを紹介します。

ent とは

ent は Meta が開発した go言語 向けの ORM です。
以下の特徴があります

  • DB スキーマを Go のオブジェクトとしてモデリングできる
  • どんなリレーションでも辿ることができる
  • 100%型安全
  • マルチドライバ(MySQL、MariaDB、TiDB、PostgreSQL、CockroachDB、SQLite、Gremlin をサポート)

今回の技術選定では、主に次の 2 点を検討しました。

  1. ORM を使うべきか
  2. マイグレーションをどう管理するか

ORM の使用有無と選定について

広告領域では、しばしば複雑なクエリが必要になります。
ORM では表現しにくいケースも多く、以前関わっていたプロジェクトでは ORM を使わず、クエリジェネレーターまたは生 SQL を直接記述する方針を採っていました。

しかし、この方法では、複数のリレーションを跨ぐ処理が増えるほど SQL が肥大化し、コードが複雑化するという課題がありました。

そのため今回は、

  • 基本は ORM を使う
  • ORM で表現が難しい箇所は生 SQL を併用する

というハイブリッド方針を採用することにしました。

ORM を採用するとなると、次はどの ORM を使うかという選択になります。
検討したのは以下の 3 つです。

  1. sqlc
    SQL ファーストで型安全。パフォーマンスが良い。

  2. ent
    スキーマファーストで完全型安全。コード生成が強力。

  3. gorm
    Go で広く使われているが、型は実行時にチェックされる。

私は普段 TypeScript を書く機会が多く、型安全・スキーマ志向の開発スタイルに慣れているため、今回は ent を採用しました。
また、クエリの書き方も好みでした。

// entでのinsertのサンプル
func CreateCar(ctx context.Context, client *ent.Client) (*ent.Car, error) {
    tesla, err := client.Car.
        Create().
        SetModel("Tesla").
        SetRegisteredAt(time.Now()).
        Save(ctx)
    if err != nil {
        return nil, fmt.Errorf("failed creating car: %w", err)
    }
    return tesla, nil
}

マイグレーションの方法について

今回のプロジェクトでは、ent の Versioned Migrations を採用しました。
ent 公式が推奨する方式で、atlas を使ってスキーマ差分を生成・管理する方法です。

マイグレーションは以下の手順で実行しています

  1. go のコード上で schema を変更
  2. ent でコード生成
  3. atlas で差分を検出して migration ファイルを生成する
  4. atlas が生成した SQL を apply する

image.png

ent のコード生成について

ent のコードは、デフォルトの設定の場合は、スキーマ定義と生成コードが同じディレクトリに存在してしまいわかりにくいです。

ent
├── client.go
├── config.go
├── context.go
├── ent.go
├── generate.go
├── mutation.go
... truncated
├── schema ← ここ以外は自動生成
│   └── user.go
├── tx.go
├── user
│   ├── user.go
│   └── where.go
├── user.go
├── user_create.go
├── user_delete.go
├── user_query.go
└── user_update.go

今回は、以下の記事を参考にし、コードの生成場所を分離しました

終わりに

今回の記事では、実際のプロジェクトでentを採用した理由や使い方などを紹介しました。

個人的には、型安全性が高くクエリ周りが書きやすいところに魅力を感じています。
最後まで読んでいただきありがとうございました。

▼ 新卒エンジニア研修のご紹介

レアゾン・ホールディングスでは、2025 年新卒エンジニア研修にて「個のスキル」と「チーム開発力」の両立を重視した育成に取り組んでいます。 実際の研修の様子や、若手エンジニアの成長ストーリーは以下の記事で詳しくご紹介していますので、ぜひご覧ください!

▼ 採用情報

レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。 現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?