【PostgreSQL】DBスキーマの差分検出ツールmigraを使ってみた
PostgreSQLのデータベーススキーマの差分を検出するPython製のツールmigraを使ってみました。
インストール
pipでインストールできます。DB接続にはpsycopg2を使用しているので、未インストールであれば一緒にインストールする必要があります。
$ pip install migra
$ pip install psycopg2
動作確認
データベースとテーブル作成
データベースを2つ作成して差分を表示してみます。psqlでローカルのPostgreSQLに接続後に以下のDDLを実行します。
# データベースexample1を作成
$ create database example1;
# example1に接続
$ ¥c example1
# テーブル作成
$ create table price (
id serial,
product_id int not null,
price numeric not null,
updated_at timestamp with time zone not null,
constraint pk_price primary key(id)
);
$ create table price_history (
id serial,
product_id int not null,
price numeric not null,
updated_at timestamp with time zone not null,
constraint pk_price_history primary key(id)
);
$ ¥c postgres
# データベースexample2を作成
$ create database example2;
# example2に接続
$ ¥c example2
# priceテーブルのみ作成
$ create table price (
id serial,
product_id int not null,
price numeric not null,
updated_at timestamp with time zone not null,
constraint pk_price primary key(id)
);
差分検出
作成したデータベースに対してmigraを実行します。1つ目の引数のデータベースから2つ目の引数のデータベースへマイグレーションするために必要なSQLを出力します。
差分が無い場合は何も出力されません。
$ migra --unsafe postgresql://postgres:xxxxx@localhost:5432/example2 postgresql://postgres:xxxxx@localhost:5432/example1
以下のSQLが出力されました。シーケンスの作成や主キー制約などは個別のSQLになるようです。シーケンスによるIDの採番や主キー制約部分はCREATE TABLEの中に書くことができるので、生成されるSQLは少し冗長に思えます。
create sequence "public"."price_history_id_seq";
create table "public"."price_history" (
"id" integer not null default nextval('price_history_id_seq'::regclass),
"product_id" integer not null,
"price" numeric not null,
"updated_at" timestamp with time zone not null
);
alter sequence "public"."price_history_id_seq" owned by "public"."price_history"."id";
CREATE UNIQUE INDEX pk_price_history ON public.price_history USING btree (id);
alter table "public"."price_history" add constraint "pk_price_history" PRIMARY KEY using index "pk_price_history";
example2に対して以下のDDLを実行後に再びmigraを実行すると差分は無くなりました。
create table price_history (
id serial,
product_id int not null,
price numeric not null,
updated_at timestamp with time zone not null,
constraint pk_price_history primary key(id)
);
テーブル数が多くないのであればマイグレーションするSQLは手作業で作成し、マイグレーションの結果確認にmigraを使うのが良いと思いました。