LoginSignup
3
1

More than 1 year has passed since last update.

ElixirでPostgreSQLのテーブル情報を取得しカラムの検証をする

Last updated at Posted at 2021-10-11

はじめに

目的
migrateで作ったDBのカラムが正しく作られているか検証をする
DBを作るにphx.newが楽なため今回はphx.serverを立ち上げませんが、phx.newを使います

この記事の実行環境

$ elixir -v
Erlang/OTP 24 [erts-12.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Elixir 1.12.2 (compiled with Erlang/OTP 22)

$ mix phx.new -v
Phoenix installer v1.6.0

$ psql
psql (12.8 (Ubuntu 12.8-0ubuntu0.20.04.1))
Type "help" for help.

プロジェクト作成

$ mix phx.new sample
* creating sample/config/config.exs
* creating sample/config/dev.exs
        〜  中略 〜
* creating sample/priv/static/images/phoenix.png
* creating sample/priv/static/favicon.ico

Fetch and install dependencies? [Yn] y

* running mix deps.get
* running mix deps.compile

We are almost there! The following steps are missing:

    $ cd sample

Then configure your database in config/dev.exs and run:

    $ mix ecto.create

Start your Phoenix app with:

    $ mix phx.server

You can also run your app inside IEx (Interactive Elixir) as:

    $ iex -S mix phx.server

ビルド〜テスト

$ cd sample
$ mix ecto.create
Compiling 14 files (.ex)
Generated sample app
The database for Sample.Repo has been created
$ mix test
==> connection
Compiling 1 file (.ex)
Generated connection app
==> gettext
Compiling 1 file (.erl)
Compiling 20 files (.ex)
Generated gettext app
        〜  中略 〜
Generated sample app
...

Finished in 0.04 seconds (0.03s async, 0.01s sync)
3 tests, 0 failures

Randomized with seed 704118

実験用のテーブルを作る

$ mix phx.gen.context Accounts User users name:string
* creating lib/sample/accounts/user.ex
* creating priv/repo/migrations/20211011073708_create_users.exs
* creating lib/sample/accounts.ex
* injecting lib/sample/accounts.ex
* creating test/sample/accounts_test.exs
* injecting test/sample/accounts_test.exs
* creating test/support/fixtures/accounts_fixtures.ex
* injecting test/support/fixtures/accounts_fixtures.ex

Remember to update your repository by running migrations:

    $ mix ecto.migrate

$  mix ecto.migrate
Compiling 2 files (.ex)
Generated sample app

16:38:25.004 [info]  == Running 20211011073708 Sample.Repo.Migrations.CreateUsers.change/0 forward

16:38:25.011 [info]  create table users

16:38:25.020 [info]  == Migrated 20211011073708 in 0.0s

検証するプログラムを作成する

test/priv/repo/migrations/20211011073708_create_users_test.exs
defmodule CreateUsersTest do
  use Sample.DataCase

  test "create users test" do
    [table: "users", col: "name", type: "varchar", notnull: :false, length: 255]
    |> assert_col()
  end

  defp assert_col(param) do
    {:ok, %{rows: result}} = Ecto.Adapters.SQL.query(Sample.Repo, create_sql(), Keyword.values(param))

    result
    |> List.first()
    |> List.first()
    |> assert()
  end

  defp create_sql() do
    """
    SELECT count(*) = 1 AS result
    FROM pg_attribute AS a
        INNER JOIN pg_type AS b on a.atttypid = b.oid
        INNER JOIN pg_class AS c on a.attrelid = c.oid
    WHERE c.relname = $1
        AND a.attname = $2
        AND b.typname = $3
        AND a.attnotnull = $4::boolean
        AND a.atttypmod =  $5::integer + 4;

    """
  end
end

実行

正常に終了します

$ mix test
............

Finished in 0.4 seconds (0.2s async, 0.2s sync)
12 tests, 0 failures

Randomized with seed 468455

エラーを発生させる

col:namecol:name1に変更します

test/priv/repo/migrations/20211011073708_create_users_test.exs
  #〜  中略 〜
  test "create users test" do
    %{table: :users, col: :name1, type: :varchar, notnull: :FALSE, length: 255}

    |> assert_col()
  end
 #〜  中略 〜

エラーになりました

$ mix test
..........

  1) test create users test (CreateUsersTest)
     test/priv/repo/migrations/20211011073708_create_users_test.exs:4
     Expected truthy, got false
     code: assert List.first(List.first(ret))
     arguments:

         # 1
         [false]

     stacktrace:
       test/priv/repo/migrations/20211011073708_create_users_test.exs:16: CreateUsersTest.assert_col/1
       test/priv/repo/migrations/20211011073708_create_users_test.exs:6: (test)

.

Finished in 0.4 seconds (0.2s async, 0.2s sync)
12 tests, 1 failure

Randomized with seed 542539
3
1
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
3
1