{"id":18034008,"url":"https://github.com/miolab/ecto_postgres","last_synced_at":"2026-05-01T09:31:23.182Z","repository":{"id":114315142,"uuid":"264368593","full_name":"miolab/ecto_postgres","owner":"miolab","description":"EctoとPostgreSQLでいろいろ試すリポジトリ（IExベース）","archived":false,"fork":false,"pushed_at":"2020-05-19T04:51:07.000Z","size":42,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-04T22:41:32.482Z","etag":null,"topics":["ecto-db","elixir","iex","postgresql"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/miolab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-16T05:46:30.000Z","updated_at":"2020-08-26T00:04:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"8280be4d-2efc-4282-a9ef-94a6fd3a3676","html_url":"https://github.com/miolab/ecto_postgres","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/miolab/ecto_postgres","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miolab%2Fecto_postgres","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miolab%2Fecto_postgres/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miolab%2Fecto_postgres/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miolab%2Fecto_postgres/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/miolab","download_url":"https://codeload.github.com/miolab/ecto_postgres/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miolab%2Fecto_postgres/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32492087,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ecto-db","elixir","iex","postgresql"],"created_at":"2024-10-30T11:09:16.879Z","updated_at":"2026-05-01T09:31:23.166Z","avatar_url":"https://github.com/miolab.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ecto \u0026 PostgreSQL\n\n`Ecto` と `PostgreSQL` でいろいろお試しします。\n\n- __Ecto__\n\n  `Elixir`の\n  - Databaseラッパー\n\n  - クエリジェネレーター\n\n- 参考\n\n  - [Hex](https://hex.pm/packages/ecto_sql)\n\n  - [Hexdocs](https://hexdocs.pm/ecto/getting-started.html)\n\n---\n\n## 実行環境\n\n- macOS\n\n  ```bash\n  $ psql --version\n  psql (PostgreSQL) 12.2\n\n  $ elixir --version\n  Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]\n\n  Elixir 1.9.2 (compiled with Erlang/OTP 22)\n  ```\n\n---\n\n## EctoでDB作成\n\nHexdocsを元に実行します。\n\n- __bash__\n\n  ```bash\n  $ mix new friends --sup\n\n  * creating README.md\n  * creating .formatter.exs\n  * creating .gitignore\n  * creating mix.exs\n  * creating lib\n  * creating lib/friends.ex\n  * creating lib/friends/application.ex\n  * creating test\n  * creating test/test_helper.exs\n  * creating test/friends_test.exs\n\n  Your Mix project was created successfully.\n  You can use \"mix\" to compile it, test it, and more:\n\n      cd friends\n      mix test\n\n  Run \"mix help\" for more commands.\n  ```\n\n  ```bash\n  cd friends\n  ```\n\n- mix.exs\n\n  ```elixir\n  defp deps do\n    [\n      {:ecto_sql, \"~\u003e 3.0\"},    -\u003e add\n      {:postgrex, \"\u003e= 0.0.0\"}   -\u003e add\n  ```\n\n- __bash__\n\n  ```bash\n  $ mix deps.get\n\n  Resolving Hex dependencies...\n  Dependency resolution completed:\n  New:\n    connection 1.0.4\n    db_connection 2.2.2\n    decimal 1.8.1\n    ecto 3.4.4\n    ecto_sql 3.4.3\n    postgrex 0.15.4\n    telemetry 0.4.1\n  * Getting ecto_sql (Hex package)\n  * Getting postgrex (Hex package)\n  * Getting connection (Hex package)\n  * Getting db_connection (Hex package)\n  * Getting decimal (Hex package)\n  * Getting ecto (Hex package)\n  * Getting telemetry (Hex package)\n  ```\n\n  ```bash\n  $ mix ecto.gen.repo -r Friends.Repo\n\n  ==\u003e connection\n  Compiling 1 file (.ex)\n  Generated connection app\n  ===\u003e Compiling telemetry\n  ==\u003e decimal\n  Compiling 1 file (.ex)\n  Generated decimal app\n  ==\u003e db_connection\n  Compiling 14 files (.ex)\n  Generated db_connection app\n  ==\u003e ecto\n  Compiling 55 files (.ex)\n  Generated ecto app\n  ==\u003e postgrex\n  Compiling 61 files (.ex)\n  Generated postgrex app\n  ==\u003e ecto_sql\n  Compiling 26 files (.ex)\n  Generated ecto_sql app\n  ==\u003e friends\n  * creating lib/friends\n  * creating lib/friends/repo.ex\n  * creating config/config.exs\n  Don't forget to add your new repo to your supervision tree\n  (typically in lib/friends/application.ex):\n\n      {Friends.Repo, []}\n\n  And to add it to the list of ecto repositories in your\n  configuration files (so Ecto tasks work as expected):\n\n      config :friends,\n        ecto_repos: [Friends.Repo]\n  ```\n\n- config/config.exs\n\n  ```elixir\n  config :friends, Friends.Repo,\n    database: \"friends_repo\",\n    username: \"postgres\",\n    password: \"postgres\",\n    hostname: \"localhost\"\n\n  config :friends, ecto_repos: [Friends.Repo]  --\u003e add\n  ```\n\n- lib/friends/application\n\n  ```elixir\n  def start(_type, _args) do\n    children = [\n      Friends.Repo,    --\u003e add\n  ```\n\n- __bash__\n\n  ```bash\n  $ mix ecto.create\n\n  Compiling 3 files (.ex)\n  Generated friends app\n  The database for Friends.Repo has been created\n  ```\n\n#### 結果確認（DB）\n\n```postgres\n$ psql -l\n                                     List of databases\n         Name         |  Owner   | Encoding |   Collate   |    Ctype    | Access privileges \n----------------------+----------+----------+-------------+-------------+-------------------\n friends_repo         | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | \n .\n .\n .\n```\n\n- Ectoでの __DBの作成__ に成功しました。\n\n---\n\n## DBセットアップ（マイグレーション 〜 テーブル作成）\n\n- __bash__\n\n  ```bash\n  $ mix ecto.gen.migration create_people\n\n  * creating priv/repo/migrations\n  * creating priv/repo/migrations/20200517041113_create_people.exs\n  ```\n\n- priv/repo/migrations/20200517041113_create_people.exs\n\n  ```elixir\n    def change do\n      create table(:people) do    --\u003e add\n        add :first_name, :string  --\u003e add\n        add :last_name, :string   --\u003e add\n        add :age, :integer        --\u003e add\n      end\n  ```\n\n- __bash__\n\n  ```bash\n  $ mix ecto.migrate\n\n  13:28:21.372 [info]  == Running 20200517041113 Friends.Repo.Migrations.CreatePeople.change/0 forward\n\n  13:28:21.373 [info]  create table people\n\n  13:28:21.382 [info]  == Migrated 20200517041113 in 0.0s\n  ```\n\n#### 結果確認（テーブル）\n\n```postgres\n$ psql friends_repo\npsql (12.2)\nType \"help\" for help.\n\nfriends_repo=# \\dt\n               List of relations\n Schema |       Name        | Type  |  Owner   \n--------+-------------------+-------+----------\n public | people            | table | postgres\n public | schema_migrations | table | postgres\n(2 rows)\n\nfriends_repo=# \\d people\n                                      Table \"public.people\"\n   Column   |          Type          | Collation | Nullable |              Default               \n------------+------------------------+-----------+----------+------------------------------------\n id         | bigint                 |           | not null | nextval('people_id_seq'::regclass)\n first_name | character varying(255) |           |          | \n last_name  | character varying(255) |           |          | \n age        | integer                |           |          | \nIndexes:\n    \"people_pkey\" PRIMARY KEY, btree (id)\n\n```\n\n- Ectoでの __DBテーブル作成__ に成功しました。\n\n- （メモ）\n\n  - マイグレーションでミスがあった場合、`mix ecto.rollback` で変更を元に戻すことが可能。  \n  （その後、変更修正してから、再度 `mix ecto.create`を実行する）\n\n  - この段階で `mix ecto.rollback` すると、いま作成したばかりのテーブルを削除可能。\n\n---\n\n## レコード作成（Create）\n\n- `insert()`\n\n### スキーマ作成\n\n- ファイル作成： `lib/friends/person.ex`\n\n  ```elixir\n  defmodule Friends.Person do\n    use Ecto.Schema\n\n    schema \"people\" do\n      field :first_name, :string\n      field :last_name, :string\n      field :age, :integer\n    end\n  end\n  ```\n\n- `$ iex -S mix` で検証\n\n  ```elixir\n  iex(1)\u003e person = %Friends.Person{}\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:built, \"people\"\u003e,\n    age: nil,\n    first_name: nil,\n    id: nil,\n    last_name: nil\n  }\n\n  iex(2)\u003e person = %Friends.Person{age: 28}\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:built, \"people\"\u003e,\n    age: 28,\n    first_name: nil,\n    id: nil,\n    last_name: nil\n  }\n\n  iex(3)\u003e person.age\n  28\n\n  iex(4)\u003e Friends.Repo.insert(person)\n\n  15:42:21.463 [debug] QUERY OK db=2.9ms decode=1.2ms queue=1.1ms idle=27.4ms\n  INSERT INTO \"people\" (\"age\") VALUES ($1) RETURNING \"id\" [28]\n  {:ok,\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: 28,\n    first_name: nil,\n    id: 1,\n    last_name: nil\n  }}\n  ```\n\n### バリデーション機能実装\n\n- `lib/friends/person.ex` の `defmodule` 内に、以下を追加\n\n  ```elixir\n  def changeset(person, params \\\\ %{}) do\n    person\n    |\u003e Ecto.Changeset.cast(params, [:first_name, :last_name, :age])\n    |\u003e Ecto.Changeset.validate_required([:first_name, :last_name])\n  end\n  ```\n\n- `$ iex -S mix` で検証 _（バリデーションエラー パターン）_\n\n  ```elixir\n  iex(1)\u003e person = %Friends.Person{}\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:built, \"people\"\u003e,\n    age: nil,\n    first_name: nil,\n    id: nil,\n    last_name: nil\n  }\n\n  iex(2)\u003e changeset = Friends.Person.changeset(person, %{})\n  #Ecto.Changeset\u003c\n    action: nil,\n    changes: %{},\n    errors: [\n      first_name: {\"can't be blank\", [validation: :required]},\n      last_name: {\"can't be blank\", [validation: :required]}\n    ],\n    data: #Friends.Person\u003c\u003e,\n    valid?: false\n  \u003e\n\n  iex(3)\u003e Friends.Repo.insert(changeset)\n  {:error,\n  #Ecto.Changeset\u003c\n    action: :insert,\n    changes: %{},\n    errors: [\n      first_name: {\"can't be blank\", [validation: :required]},\n      last_name: {\"can't be blank\", [validation: :required]}\n    ],\n    data: #Friends.Person\u003c\u003e,\n    valid?: false\n  \u003e}\n\n  iex(4)\u003e changeset.valid?\n  false\n  ```\n\n  - ちゃんと `:error` が返り、バリデーションが効いていることを確認できました。\n\n- `$ iex -S mix` で検証 _（サクセス パターン）_\n\n  データの `INSERT` (CREATE処理) まで合わせて実行します。\n\n  ```\n  iex(5)\u003e person = %Friends.Person{}\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:built, \"people\"\u003e,\n    age: nil,\n    first_name: nil,\n    id: nil,\n    last_name: nil\n  }\n\n  iex(6)\u003e changeset = Friends.Person.changeset(person, %{first_name: \"im\", last_name: \"miolab\"})\n  #Ecto.Changeset\u003c\n    action: nil,\n    changes: %{first_name: \"im\", last_name: \"miolab\"},\n    errors: [],\n    data: #Friends.Person\u003c\u003e,\n    valid?: true\n  \u003e\n\n  iex(7)\u003e changeset.errors\n  []\n\n  iex(8)\u003e changeset.valid?\n  true\n\n  iex(9)\u003e Friends.Repo.insert(changeset)\n\n  16:15:47.461 [debug] QUERY OK db=1.7ms decode=1.1ms queue=1.4ms idle=421.1ms\n  INSERT INTO \"people\" (\"first_name\",\"last_name\") VALUES ($1,$2) RETURNING \"id\" [\"im\", \"miolab\"]\n  {:ok,\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: nil,\n    first_name: \"im\",\n    id: 2,\n    last_name: \"miolab\"\n  }}\n  ```\n\n#### 結果確認（テーブル）\n\n```postgres\n$ psql friends_repo\npsql (12.2)\nType \"help\" for help.\n\nfriends_repo=# select * from people;\n id | first_name | last_name | age \n----+------------+-----------+-----\n  1 |            |           |  28\n  2 | im         | miolab    |    \n(2 rows)\n```\n\n- Ectoでの __CREATE__ 処理に成功しました。\n\n- `id: 2` レコードで、`first_name` `last_name` のバリデーションも効いています。\n\n---\n\n## クエリ実行\n\n- 事前準備として、DBを再作成します。\n\n  - PostgreSQL\n\n    ```postgres\n    # exit\n    ```\n\n  - __bash__\n\n    ```bash\n    $ mix ecto.drop\n    The database for Friends.Repo has been dropped\n\n    $ mix ecto.create\n    The database for Friends.Repo has been created\n\n    $ mix ecto.migrate\n\n    08:14:06.052 [info]  == Running 20200517041113 Friends.Repo.Migrations.CreatePeople.change/0 forward\n\n    08:14:06.055 [info]  create table people\n\n    08:14:06.078 [info]  == Migrated 20200517041113 in 0.0s\n    ```\n\n  - PostgreSQL\n\n    ```postgres\n    $ psql friends_repo\n\n    friends_repo=# select * from people;\n    id | first_name | last_name | age \n    ----+------------+-----------+-----\n    (0 rows)\n    ```\n\n    DBが再作成されました。\n\n\n- `$ iex -S mix` で以下を実行。\n\n  クエリを構築 → クエリをリポジトリに渡す → DBに対してクエリを実行\n\n  ```elixir\n  iex(1)\u003e people = [\n  ...(1)\u003e %Friends.Person{first_name: \"im\", last_name: \"miolab\", age: 28},\n  ...(1)\u003e %Friends.Person{first_name: \"foo\", last_name: \"miolab\", age: 27},\n  ...(1)\u003e %Friends.Person{first_name: \"foobar\", last_name: \"hogehoge\", age: 26},\n  ...(1)\u003e %Friends.Person{first_name: \"eli\", last_name: \"xir\", age: 26},\n  ...(1)\u003e ]\n  [\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:built, \"people\"\u003e,\n      age: 28,\n      first_name: \"im\",\n      id: nil,\n      last_name: \"miolab\"\n    },\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:built, \"people\"\u003e,\n      age: 27,\n      first_name: \"foo\",\n      id: nil,\n      last_name: \"miolab\"\n    },\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:built, \"people\"\u003e,\n      age: 26,\n      first_name: \"foobar\",\n      id: nil,\n      last_name: \"hogehoge\"\n    },\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:built, \"people\"\u003e,\n      age: 26,\n      first_name: \"eli\",\n      id: nil,\n      last_name: \"xir\"\n    }\n  ]\n\n  iex(2)\u003e Enum.each(people, fn(person) -\u003e Friends.Repo.insert(person) end)\n\n  10:17:19.023 [debug] QUERY OK db=2.3ms decode=1.0ms queue=2.6ms idle=1198.7ms\n  INSERT INTO \"people\" (\"age\",\"first_name\",\"last_name\") VALUES ($1,$2,$3) RETURNING \"id\" [28, \"im\", \"miolab\"]\n\n  10:17:19.027 [debug] QUERY OK db=1.1ms queue=1.1ms idle=1208.3ms\n  INSERT INTO \"people\" (\"age\",\"first_name\",\"last_name\") VALUES ($1,$2,$3) RETURNING \"id\" [27, \"foo\", \"miolab\"]\n\n  10:17:19.030 [debug] QUERY OK db=1.0ms queue=0.9ms idle=1210.7ms\n  INSERT INTO \"people\" (\"age\",\"first_name\",\"last_name\") VALUES ($1,$2,$3) RETURNING \"id\" [26, \"foobar\", \"hogehoge\"]\n\n  10:17:19.032 [debug] QUERY OK db=1.0ms queue=0.9ms idle=1212.8ms\n  INSERT INTO \"people\" (\"age\",\"first_name\",\"last_name\") VALUES ($1,$2,$3) RETURNING \"id\" [26, \"eli\", \"xir\"] \n  :ok\n  ```\n\n  （※ `changeset` 不経由）\n\n#### 結果確認（テーブル）\n\n  ```postgres\n  friends_repo=# select * from people;\n\n   id | first_name | last_name | age\n  ----+------------+-----------+-----\n    1 | im         | miolab    |  28\n    2 | foo        | miolab    |  27\n    3 | foobar     | hogehoge  |  26\n    4 | eli        | xir       |  26\n  (4 rows)\n  ```\n\n---\n\n## レコード取得（Read）\n\n- `get()`\n- `get_by()`\n- `where()`\n\n\n`$ iex -S mix` で確認。\n\n- 最初のレコード 取得\n\n  ```elixir\n  iex(1)\u003e Friends.Person |\u003e Ecto.Query.first |\u003e Friends.Repo.one\n\n  11:17:20.928 [debug] QUERY OK source=\"people\" db=0.8ms decode=1.6ms queue=1.5ms idle=1791.5ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 ORDER BY p0.\"id\" LIMIT 1 []\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: 28,\n    first_name: \"im\",\n    id: 1,\n    last_name: \"miolab\"\n  }\n  ```\n\n- 最後のレコード 取得\n\n  ```elixir\n  iex(2)\u003e Friends.Person |\u003e Ecto.Query.last |\u003e Friends.Repo.one\n\n  11:17:46.505 [debug] QUERY OK source=\"people\" db=1.5ms queue=2.5ms idle=1377.0ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 ORDER BY p0.\"id\" DESC LIMIT 1 []\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: 26,\n    first_name: \"eli\",\n    id: 4,\n    last_name: \"xir\"\n  }\n  ```\n\n- __全レコード__ 取得\n\n  ```elixir\n  iex(3)\u003e Friends.Person |\u003e Friends.Repo.all\n\n  11:19:58.105 [debug] QUERY OK source=\"people\" db=0.3ms queue=0.4ms idle=1981.1ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 []\n  [\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n      age: 28,\n      first_name: \"im\",\n      id: 1,\n      last_name: \"miolab\"\n    },\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n      age: 27,\n      first_name: \"foo\",\n      id: 2,\n      last_name: \"miolab\"\n    },\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n      age: 26,\n      first_name: \"foobar\",\n      id: 3,\n      last_name: \"hogehoge\"\n    },\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n      age: 26,\n      first_name: \"eli\",\n      id: 4,\n      last_name: \"xir\"\n    }\n  ]\n  ```\n\n- __`id` を指定__ してレコード取得\n\n  ```elixir\n  iex(4)\u003e Friends.Person |\u003e Friends.Repo.get(1)\n\n  11:21:08.927 [debug] QUERY OK source=\"people\" db=1.2ms queue=1.6ms idle=1801.0ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 WHERE (p0.\"id\" = $1) [1]\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: 28,\n    first_name: \"im\",\n    id: 1,\n    last_name: \"miolab\"\n  }\n\n  iex(5)\u003e Friends.Person |\u003e Friends.Repo.get(2)\n\n  11:21:14.877 [debug] QUERY OK source=\"people\" db=3.9ms idle=1749.7ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 WHERE (p0.\"id\" = $1) [2]\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: 27,\n    first_name: \"foo\",\n    id: 2,\n    last_name: \"miolab\"\n  }\n  ```\n\n- __カラム属性__ に基づいてレコードを取得\n\n  ```elixir\n  iex(6)\u003e Friends.Person |\u003e Friends.Repo.get_by(first_name: \"im\")\n\n  11:23:40.635 [debug] QUERY OK source=\"people\" db=1.4ms queue=5.4ms idle=1504.6ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 WHERE (p0.\"first_name\" = $1) [\"im\"]\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: 28,\n    first_name: \"im\",\n    id: 1,\n    last_name: \"miolab\"\n  }\n  ```\n\n- フィルタリング抽出（`Ecto.Query` 併用）\n\n  ```elixir\n  iex(7)\u003e require Ecto.Query\n  Ecto.Query\n\n  iex(8)\u003e Friends.Person |\u003e Ecto.Query.where(last_name: \"miolab\") |\u003e Friends.Repo.all\n\n  11:34:11.847 [debug] QUERY OK source=\"people\" db=0.5ms queue=1.5ms idle=1721.2ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 WHERE (p0.\"last_name\" = 'miolab') []\n  [\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n      age: 28,\n      first_name: \"im\",\n      id: 1,\n      last_name: \"miolab\"\n    },\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n      age: 27,\n      first_name: \"foo\",\n      id: 2,\n      last_name: \"miolab\"\n    }\n  ]\n  ```\n\n  - 別記法\n\n    ```elixir\n    iex(9)\u003e Ecto.Query.from(p in Friends.Person, where: p.last_name == \"miolab\") |\u003e Friends.Repo.all\n\n    12:02:34.174 [debug] QUERY OK source=\"people\" db=0.9ms queue=0.1ms idle=1563.1ms\n    SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 WHERE (p0.\"last_name\" = 'miolab') []\n    [\n      %Friends.Person{\n        __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n        age: 28,\n        first_name: \"im\",\n        id: 1,\n        last_name: \"miolab\"\n      },\n      %Friends.Person{\n        __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n        age: 27,\n        first_name: \"foo\",\n        id: 2,\n        last_name: \"miolab\"\n      }\n    ]\n    ```\n\n  - _Note_ : 変数をクエリ内で展開する場合は、`^` （ピン演算子）が必要。\n\n    ```elixir\n    iex(10)\u003e last_name_miolab = \"miolab\"\n    \"miolab\"\n\n    iex(11)\u003e Friends.Person |\u003e Ecto.Query.where(last_name: ^last_name_miolab) |\u003e Friends.Repo.all\n\n    11:52:23.130 [debug] QUERY OK source=\"people\" db=1.3ms queue=2.7ms idle=1518.1ms\n    SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 WHERE (p0.\"last_name\" = $1) [\"miolab\"]\n    [\n      %Friends.Person{\n        __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n        age: 28,\n        first_name: \"im\",\n        id: 1,\n        last_name: \"miolab\"\n      },\n      %Friends.Person{\n        __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n        age: 27,\n        first_name: \"foo\",\n        id: 2,\n        last_name: \"miolab\"\n      }\n    ]\n\n    iex(12)\u003e Ecto.Query.from(p in Friends.Person, where: p.last_name == ^last_name_miolab) |\u003e Friends.Repo.all\n\n    12:03:02.104 [debug] QUERY OK source=\"people\" db=2.0ms idle=1493.0ms\n    SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 WHERE (p0.\"last_name\" = $1) [\"miolab\"]\n    [\n      %Friends.Person{\n        __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n        age: 28,\n        first_name: \"im\",\n        id: 1,\n        last_name: \"miolab\"\n      },\n      %Friends.Person{\n        __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n        age: 27,\n        first_name: \"foo\",\n        id: 2,\n        last_name: \"miolab\"\n      }\n    ]\n    ```\n\n  - クエリのアレンジ（使用例）\n\n    `last_name` 抽出に、`first_name` 抽出を追加して `AND` 検索となるようクエリをアレンジします。\n\n    ```elixir\n    iex(13)\u003e query = Friends.Person |\u003e Ecto.Query.where(last_name: \"miolab\")\n    #Ecto.Query\u003cfrom p0 in Friends.Person, where: p0.last_name == \"miolab\"\u003e\n\n    iex(14)\u003e query_fullname = query |\u003e Ecto.Query.where(first_name: \"im\")\n    #Ecto.Query\u003cfrom p0 in Friends.Person, where: p0.last_name == \"miolab\",\n    where: p0.first_name == \"im\"\u003e\n\n    iex(15)\u003e query_fullname |\u003e Friends.Repo.all\n\n    12:20:26.074 [debug] QUERY OK source=\"people\" db=0.2ms idle=1460.8ms\n    SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 WHERE (p0.\"last_name\" = 'miolab') AND (p0.\"first_name\" = 'im') []\n    [\n      %Friends.Person{\n        __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n        age: 28,\n        first_name: \"im\",\n        id: 1,\n        last_name: \"miolab\"\n      }\n    ]\n    ```\n\n---\n\n## レコード更新（Update）\n\n- `update()`\n\n`$ iex -S mix` で確認。\n\n- iex\n\n  ```elixir\n  iex(1)\u003e require Ecto.Query\n  Ecto.Query\n\n  iex(2)\u003e person = Friends.Person |\u003e Ecto.Query.first |\u003e Friends.Repo.one\n\n  13:09:01.291 [debug] QUERY OK source=\"people\" db=0.9ms decode=1.5ms queue=1.3ms idle=1885.6ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 ORDER BY p0.\"id\" LIMIT 1 []\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: 28,\n    first_name: \"im\",\n    id: 1,\n    last_name: \"miolab\"\n  }\n\n  iex(3)\u003e changeset = Friends.Person.changeset(person, %{age: 18})\n  #Ecto.Changeset\u003c\n    action: nil,\n    changes: %{age: 18},\n    errors: [],\n    data: #Friends.Person\u003c\u003e,\n    valid?: true\n  \u003e\n\n  iex(4)\u003e Friends.Repo.update(changeset)\n\n  13:10:28.235 [debug] QUERY OK db=1.8ms queue=2.5ms idle=1835.9ms\n  UPDATE \"people\" SET \"age\" = $1 WHERE \"id\" = $2 [18, 1]\n  {:ok,\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: 18,\n    first_name: \"im\",\n    id: 1,\n    last_name: \"miolab\"\n  }}\n  ```\n\n#### 結果確認（テーブル）\n\n  ```postgres\n  friends_repo=# select * from people;\n   id | first_name | last_name | age\n  ----+------------+-----------+-----\n    2 | foo        | miolab    |  27\n    3 | foobar     | hogehoge  |  26\n    4 | eli        | xir       |  26\n    1 | im         | miolab    |  18\n  (4 rows)\n  ```\n\n---\n\n## レコード削除（Delete）\n\n- `delete()`\n\n`$ iex -S mix` で確認。\n\n- iex\n\n  `id: 3` のレコードを削除します。\n\n  ```elixir\n  iex(5)\u003e person_delete = Friends.Repo.get(Friends.Person, 3)\n\n  13:44:06.427 [debug] QUERY OK source=\"people\" db=0.8ms idle=1014.5ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 WHERE (p0.\"id\" = $1) [3]\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n    age: 26,\n    first_name: \"foobar\",\n    id: 3,\n    last_name: \"hogehoge\"\n  }\n\n  iex(6)\u003e Friends.Repo.delete(person_delete)\n\n  13:44:47.048 [debug] QUERY OK db=2.4ms queue=2.1ms idle=1632.1ms\n  DELETE FROM \"people\" WHERE \"id\" = $1 [3]\n  {:ok,\n  %Friends.Person{\n    __meta__: #Ecto.Schema.Metadata\u003c:deleted, \"people\"\u003e,\n    age: 26,\n    first_name: \"foobar\",\n    id: 3,\n    last_name: \"hogehoge\"\n  }}\n  ```\n\n#### 結果確認（テーブル）\n\n- iex\n\n  ```\n  iex(7)\u003e Friends.Person |\u003e Friends.Repo.all\n\n  13:45:27.760 [debug] QUERY OK source=\"people\" db=0.5ms queue=0.9ms idle=1347.4ms\n  SELECT p0.\"id\", p0.\"first_name\", p0.\"last_name\", p0.\"age\" FROM \"people\" AS p0 []\n  [\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n      age: 27,\n      first_name: \"foo\",\n      id: 2,\n      last_name: \"miolab\"\n    },\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n      age: 26,\n      first_name: \"eli\",\n      id: 4,\n      last_name: \"xir\"\n    },\n    %Friends.Person{\n      __meta__: #Ecto.Schema.Metadata\u003c:loaded, \"people\"\u003e,\n      age: 18,\n      first_name: \"im\",\n      id: 1,\n      last_name: \"miolab\"\n    }\n  ]\n  ```\n\n  `id: 3` のレコードが削除されていることを確認できました。\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiolab%2Fecto_postgres","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmiolab%2Fecto_postgres","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiolab%2Fecto_postgres/lists"}