LoginSignup
13
10

More than 5 years have passed since last update.

ElixirにectoでMySQLを使う

Last updated at Posted at 2015-05-13

EctoでMySQLを使いたいときに、まず $mix new mysqltest --supでプロジェクト生成します

mix.exsファイルは下のようになっています。

 defmodule Mysqltest.Mixfile do
   use Mix.Project

   def project do
     [app: :mysqltest,
      version: "0.0.1",
      elixir: "~> 1.1-dev",
      build_embedded: Mix.env == :prod,
      start_permanent: Mix.env == :prod,
      deps: deps]
   end


   def application do
     [applications: [:logger, :ecto],
      mod: {Mysqltest.App, []}]
   end

   defp deps do
     [
       {:ecto, "~>0.11.0"},
       {:mariaex, "~> 0.1"}
     ]
   end
 end

依存関係にectomariaexが必要です。

mysqltest/config/config.exsは下のようになっています

use Mix.Config

# Mysqlの場合、アダプタはEcto.Adapters.MySQL
config :mysqltest, Mysqltest.Repo,
  adapter: Ecto.Adapters.MySQL,
  database: "testdb",
  username: "root",
  password: "123"

lib/mysqltest.exファイルは下のようになっています。

defmodule Mysqltest.App do
  use Application
  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      worker(Mysqltest.Repo, []),
    ]
    opts = [strategy: :one_for_one, name: Mysqltest.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

defmodule Tenant do
  use Ecto.Model
    schema "tenant" do
      field :id, :integer
      # ectoにuuidデータタイプ存在してる
      field :uuid, :uuid
      # 参照リンク
      # http://stackoverflow.com/questions/28506589/default-datetime-with-ecto-elixir
      timestamps([{:inserted_at,:created_at}])
    end
end

# ここのMysqltest.Repoはconfig.exs設定ファイルにもあります。
defmodule Mysqltest.Repo do
  use Ecto.Repo, otp_app: :mysqltest
end

defmodule Mysqltest do
  import Ecto.Query
  def sample_query do
    # http://stackoverflow.com/questions/30163965/elixir-ecto-connect-to-an-existing-db
    query = from t in Tenant,
          where: t.id == 319,
          # 下の形で(両方とも)時間比較するときにschemaの部分でtimestamps([{:inserted_at,:created_at}])の形で定義する必要があります
      # 参照リンク http://stackoverflow.com/questions/30211217/elixir-ecto-compare-time-the-in-the-where-clause

          #where: t.created_at == ^%Ecto.DateTime{year: 2015, month: 4, day: 27, hour: 10,min: 8, sec: 42, usec: 0},
          where: t.created_at == ^Ecto.DateTime.from_erl({{2015, 4, 24}, {13, 8, 51}}),
          select: t
    [res] = Mysqltest.Repo.all(query)
    IO.inspect res
  end
end

これで$ mix deps.get; iex -S mixを実行して、

iex(1)> Mysqltest.sample_query

19:00:43.618 [debug] SELECT t0.`id`, t0.`uuid`, t0.`created_at` FROM `tenant` AS t0 WHERE (t0.`id` = 319) [] (48.1ms)
%Tenant{__meta__: %Ecto.Schema.Metadata{source: "tenant", state: :loaded},
 ax_account_id: 12345678123, created_at: {{2015, 4, 27}, {10, 8, 42, 0}},
 id: 319, uuid: "12345678-1234-1234-1234-12345678"}
%Tenant{__meta__: %Ecto.Schema.Metadata{source: "tenant", state: :loaded},
 ax_account_id: 12345678123, created_at: {{2015, 4, 27}, {10, 8, 42, 0}},
 id: 319, uuid: "12345678-1234-1234-1234-12345678"}

最初はなぜselectを行うためになぜschemaが必要ってずっと悩んでました。
上の場合はSelectを行っていました。このときにschemaに定義されたフィールドが取得されてきます
(同じようにinsertするときにschemaに定義されているフィールドだけinsertができるのでしょう、これは推測)
selectを行うだけなら、スキーマが必要は特にないです。下のリンク参照
http://stackoverflow.com/questions/28506589/default-datetime-with-ecto-elixir

13
10
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
13
10