Trying to start an Ecto repo in an Elixir v1.12 "Mix.install" script

Hi there,

I am playing around with Elixir 1.12 (rc 1) and specifically Mix.install. I would like to be able to use Ecto from a simple one-off script (running migrations and using it), because I feel this will be very useful for data exploration tasks.

So far Ecto complains for good reason, because the app I need to refer to in the Repo declaration (via otp_app: sample) does not exist (the error is ** (ArgumentError) unknown application: :sample).

Did anyone figure out how to use Ecto in that setup ?

Thanks !

– Thibaut

In case that’s useful to others here, here is the current code:

# mix run sql.exs --no-mix-exs

# TODO: use MIX_INSTALL_DIR
# https://hexdocs.pm/mix/1.12.0-rc.1/Mix.html#install/2
Mix.install([
  {:ecto_sql, "~> 3.6.1"},
  {:postgrex, ">= 0.0.0"}
])

defmodule Sample.Repo do
  use Ecto.Repo,
    otp_app: :sample, # this app is not defined!
    adapter: Ecto.Adapters.Postgres

  def init(_context, config) do
    config = Keyword.put(config, :url, "postgres://localhost:5432/sample")
    {:ok, config}
  end
end

defmodule Sample.Migration do
  use Ecto.Migration

  def up do
    create table("cars") do
      add :vin, :string
      add :brand, :string
      add :model, :integer
      add :price, :decimal
      add :production_year, :integer

      timestamps()
    end
  end

  def down do
    drop table("cars")
  end
end

require Logger

Logger.info "Connecting to db..."
{:ok, repo} = Sample.Repo.start_link()

Logger.info "Applying migrations..."
Ecto.Migrator.run(Sample.Repo, [{0, Sample.Migration}], :up)

The application env is read on Repo.start_link/0, however it is not needed if you put it explicitly to a start_link/1.

I often use snippets like the one below

Mix.install([
  :jason,
  :ecto_sql,
  :postgrex
])

defmodule Repo do
  use Ecto.Repo, adapter: Ecto.Adapters.Postgres, otp_app: :does_not_matter
end

defmodule Post do
  use Ecto.Schema

  schema "posts" do
    field(:title)
  end
end

defmodule Main do
  def main do
    {:ok, _} = Repo.start_link(database: "")

    Repo.query!("DROP TABLE IF EXISTS posts")
    Repo.query!("CREATE TABLE posts (id serial primary key, title text)")

    Repo.insert!(%Post{title: "Post 1"})
    Repo.insert!(%Post{title: "Post 2"})

    IO.inspect(Repo.all(Post))
  end
end

Main.main()
4 Likes

Excellent. Thank you!