DBの互換性には気をつけよう


SQLX + cockroachDBがまぁしんどい

Sqlxが、というより大体はpostgresとcockroachDBの微妙に互換ではないところのせいなのだが、、、

概要としては下記の通り

  • cockroachDBはINTがint8 (bigint)として記録されるが、postgresではint4
  • postgisのextensionを端折ってもcockroachは問題ないが、postgresではダメ
  • 上記に関するsqlxのmigrationのめんどくささ

背景

Rust + sqlx + cockroachDBでバックエンドを構築しているのだが、CIとか手元のテストではpostgresを用いているためここでの微妙なDBの違いで手を焼いている。

cockroachDBはpostgres互換を謳っているが、微妙に異なるのが辛い。

当初は小さく作る上でSQLを書くだけで済んでフレームワークの学習も大変ではないという理由でsqlxを選んでいた。migrationファイルも簡単に作成できるし。

いろんな困り事

sqlxは sqlx migrate add -r hogeで、hogeに関するマイグレーションを行うupファイルとそれをrevertするdownファイルを作成する。 ここでたとえば users テーブルを作ろうとしてupファイルに

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    age INT
);

と書いてcockroachDBに適用すると、↓こうなる スクリーンショット 2026-08-03 1.28.12.png

32bit整数型を想定していたところが、cockroachDB上では64bit整数型で定義がされてしまう。 ひとまずこれに合わせてRustでDBに格納するmodelを作ると以下のようになる。

pub struct User {
    pub id: i64,
    pub age: i64,
}

そして、例えばUserを追加するクエリはsqlxを用いて以下のようになる。(idは自動採番だろというのは置いといて)

sqlx::query!(
    "INSERT INTO users(id, age) VALUE($1, $2)",
    user.id,
    user.age
).execute...

これはいい。sqlxのquery!で型をコンパイル時に検証できて嬉しいね。

問題はテスト時。テスト環境ではなぜかPostgresを使っていた。

postgresでは上記DDLでちゃんと32bit整数型としてカラムを作ってくれる。律儀に。 そのおかげで、repository層のテストでi64との型不整合が生じてCIが落ちるということが起きた。

他にも、PostGISを使いたくなった時に、本来なら

CREATE EXTENSION postgis;

が必要なのだが、dev環境のcockroachDBでは特に実行しなくても利用できていた。

一方で、postgresでは必要だったため、同様にCI上ではtestが失敗するということが起きた。その上、sqlx migrate runの実行順序にも手を入れる羽目になって、手戻りが大きくなった。

解決

cockroachDBはimageが配布されているので、CI上のテスト環境もcockroachDBにしよう! DBの〇〇互換には気をつけよう!(Java使っている時のembedding DBとか)