Want to take your software engineering career to the next level? Join the mailing list for career tips & advice Click here


A database wrapper and language integrated query for Elixir

Subscribe to updates I use ecto

Statistics on ecto

Number of watchers on Github 3355
Number of open issues 23
Average time to close an issue 3 days
Main language Elixir
Average time to merge a PR 1 day
Open pull requests 27+
Closed pull requests 50+
Last commit over 2 years ago
Repo Created about 7 years ago
Repo Last Updated over 2 years ago
Size 10.2 MB
Homepage https://hexdocs.p...
Organization / Authorelixir-ecto
Latest Releasev1.1.6
Page Updated
Do you use ecto? Leave a review!
View open issues (23)
View ecto activity
View on github
Fresh, new opensource launches 🚀🚀🚀
Software engineers: It's time to get promoted. Starting NOW! Subscribe to my mailing list and I will equip you with tools, tips and actionable advice to grow in your career.
Evaluating ecto for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)


Build Status Inline docs

Ecto is a domain specific language for writing queries and interacting with databases in Elixir. Here is an example:

# In your config/config.exs file
config :my_app, ecto_repos: [Sample.Repo]

config :my_app, Sample.Repo,
  adapter: Ecto.Adapters.Postgres,
  database: "ecto_simple",
  username: "postgres",
  password: "postgres",
  hostname: "localhost",
  port: "5432"

# In your application code
defmodule Sample.Repo do
  use Ecto.Repo,
    otp_app: :my_app

defmodule Sample.Weather do
  use Ecto.Schema

  schema "weather" do
    field :city     # Defaults to type :string
    field :temp_lo, :integer
    field :temp_hi, :integer
    field :prcp,    :float, default: 0.0

defmodule Sample.App do
  import Ecto.Query
  alias Sample.Weather
  alias Sample.Repo

  def keyword_query do
    query = from w in Weather,
         where: w.prcp > 0 or is_nil(w.prcp),
         select: w

  def pipe_query do
    |> where(city: "Krakw")
    |> order_by(:temp_lo)
    |> limit(10)
    |> Repo.all

See the getting started guide and the online documentation.

Also checkout the What's new in Ecto 2.1 free ebook to learn more about many features since Ecto 2.1 such as many_to_many, schemaless queries, concurrent testing, upsert and more. Note the book still largely applies to Ecto 3.0 as the major change in Ecto 3.0 was the removal of the outdated Ecto datetime types in favor of Elixir's Calendar types.


You need to add both Ecto and the database adapter as a dependency to your mix.exs file. The supported databases and their adapters are:

Database Ecto Adapter Dependency Ecto 2.0 compatible?
PostgreSQL Ecto.Adapters.Postgres postgrex Yes
MySQL Ecto.Adapters.MySQL mariaex Yes
MSSQL MssqlEcto mssql_ecto Yes
MSSQL Tds.Ecto tds_ecto Yes
SQLite Sqlite.Ecto2 sqlite_ecto2 Yes
Mnesia EctoMnesia.Adapter ecto_mnesia Yes

For example, if you want to use PostgreSQL, add to your mix.exs file:

defp deps do
    {:postgrex, ">= 0.0.0"},
    {:ecto, "~> 2.1"}

Then run mix deps.get in your shell to fetch the dependencies. If you want to use another database, just choose the proper dependency from the table above.

Finally, in the repository configuration, you will need to specify the adapter: respective to the chosen dependency. For PostgreSQL it is:

config :my_app, Repo,
  adapter: Ecto.Adapters.Postgres,

We are currently looking for contributions to add support for other SQL databases and folks interested in exploring non-relational databases too.

Supported Versions

Branch Support
v3.0 In development
v2.2 Bug fixes
v2.1 Security patches only
v2.0 Unsupported from 08/2017
v1.1 Security patches only
v1.0 Unsupported from 05/2017

Important links


Contributions are welcome! In particular, remember to:

  • Do not use the issues tracker for help or support requests (try Stack Overflow, IRC or mailing lists, etc).
  • For proposing a new feature, please start a discussion on elixir-ecto.
  • For bugs, do a quick search in the issues tracker and make sure the bug has not yet been reported.
  • Finally, be nice and have fun! Remember all interactions in this project follow the same Code of Conduct as Elixir.

Running tests

Clone the repo and fetch its dependencies:

$ git clone https://github.com/elixir-ecto/ecto.git
$ cd ecto
$ mix deps.get
$ mix test

Besides the unit tests above, it is recommended to run the adapter integration tests too:

# Run only PostgreSQL tests (PostgreSQL >= 9.5 is preferred for testing all Postgres features)
MIX_ENV=pg mix test

# Run all tests (unit and all adapters)
mix test.all

Building docs

$ MIX_ENV=docs mix docs

Copyright and License

Ecto and the Ecto logo are copyright (c) 2012 Plataformatec.

The Ecto logo was designed by Dane Wesolko.

Ecto source code is licensed under the Apache 2 License.

ecto open issues Ask a question     (View All Issues)
  • over 3 years Tasks ran with MySQL adapter relies on mysql client binary
  • over 3 years `cast_embed` uses schema types, not a changeset types
  • over 3 years Infix Operators
  • over 3 years Specifying an unsupported logging level causes a runtime crash
  • almost 4 years Introduce Ecto.Repo.cast or Ecto.Repo.cast_query
  • almost 4 years UNION/INTERSECT/EXCEPT support
ecto open pull requests (View All Pulls)
  • Adds support for commenting on PostgreSQL
  • Fix unique constraint errors for many_to_many inserts (#1527)
  • Add Getting Started Guide
  • Add Ecto.load
  • Add logo to README
  • Update `Multi.run/3` spec and docs
  • add complex subtypes support
  • WIP: Validate log levels at compile time
  • put_assoc with params given as string keyed maps does behave correctly
  • Allow migrations to log raw SQL if required
  • Add test for null return when selecting field
  • Fix loading when field is given with different representation
  • Promote Mnesia adapter
  • WIP: ecto association guide [DRAFT]
  • Add type checking to put_change/3 and update_change/3
  • Introduce Ecto.Adapters.SQL.Stage
  • `validate_no_conflicts_unreliably/3`
  • Add :source option for schema `field`
  • [WIP] Array based relations
  • Add schema DSLs to .formatter.exs
  • Implementing infix mathematical operators
  • add Changeset.validation_specs/1
  • Improve transaction handling
  • Custom Associations
  • [WIP] Implemented infix mathematical operators through abstract type `:number`
  • Add Dynamic Repo Configuration
  • Feature/respect schema prefix in joins
ecto questions on Stackoverflow (View All Questions)
  • Creating a unique constraint on two columns together in Ecto
  • Ecto assoc_constraint doesn't work
  • Elixir ecto: check if postgresql map column has key
  • How can I pass association to changeset in Ecto?
  • Ecto dynamic query params in phoenixframework
  • Update multiple records using ecto 2.0
  • Phoenix framework & Ecto map field
  • best way to get records created today with Ecto Phoenix?
  • How to modify an Ecto changeset before inserting it into the repo?
  • Dynamically choose field to update in elixir ecto
  • Inverse polymorphic with ecto
  • What is the simplest way to do upsert with Ecto (MySQL)
  • Is it possible to make Geospatial queries with Ecto and MongoDB?
  • Ecto equivalent for Rails' acts_as_list?
  • Ecto creating unique index failed for Mysql/Mariadb
  • UndefinedFunctionError - iex aliasing in phoenix / ecto
  • Do you need to use ecto to query a database?
  • insert_all does not create auto generated inserted_at with ecto 2.0
  • How to create a composable where with Ecto?
  • Ecto+Phoenix: How to make resource paths with a different key than :id?
  • Ecto: how to define variable default field values in schema?
  • How to query Ecto 2.0 with UUID
  • Inserting an model into a many-to-many relationship with an existing model in ecto 2
  • Minimum requirements for Ecto NoSQL adapter
  • assign inserted_at field in ecto
  • How do I translate this SQL to ecto query?
  • Phoenix - return Ecto query results to a specific client
  • Ecto Postgres install error password authentication failed
  • Using LATERAL joins in Ecto v2.0
  • elixir ecto: test has_many association
ecto list of languages used
ecto latest release notes


  • [Ecto.UUID] Remove UUID version validation as it is not part of the RFC
  • [Ecto.Adapters.Postgres] No longer add parens to migration index expression in order to support NULL/ASC/DESC


  • [Ecto.Changeset] Add unsafe_validate_unique/3 which validates uniqueness for faster feedback cycles but without data-integrity guarantees
  • [Ecto.Query] Support aggregations in type/2 in select
  • [Ecto.Schema] Support @field_source_mapper in Ecto.Schema as a mechanism to programatically set the :source option


This release adds many improvements to Ecto with a handful of bug fixes. We recommend reading the full list of enhancements below. Here are some of the highlights.

Ecto now supports specifying fields sources. This is useful when you use a database with non-conventional names, such as uppercase letters or names with hyphens:

field :name, :string, source: :NAME
field :user_name, :string, source: :"user-name"

On the migrations side, execute/2 function was added, which allows developers to describe up and down commands inside the change callback:

def change do
  execute "CREATE EXTENSION citext",
          "DROP EXTENSION citext"

The ecto.migrate and ecto.rollback tasks have also been enhanced with the --log-sql option which is helpful when debugging errors or during deployments to keep track of your production database changes.

Ecto now will also warn at compile time of invalid relationships, such as a belongs_to that points to a schema that does not exist.

The query syntax also seen some improvements: map updates are supported in subqueries, the new Ecto.Query.select_merge/3 makes it easier to write composable select clauses in queries and the type/2 macro has been extended to support casting of fragments and fields in schemaless queries.

Finally, the UPSERT support added on Ecto v2.1 is getting more improvements: the {:constraint, constraint} is now supported as conflict target and the :returning option was added to Ecto.Repo.insert/2, mirroring the behaviour of insert_all.

v2.2.0-rc.0 (2017-08-08)


  • [Ecto.Adapters] Accept IO data from adapters to reduce memory usage when performing large queries
  • [Ecto.Adapters.SQL] Also add Ecto.Repo.to_sql/2 to Ecto.Repo based on SQL adapters
  • [Ecto.Adapters.Postgres] Use the postgres database for create/drop database commands
  • [Ecto.Adapters.MySQL] Use TCP connections instead of MySQL command client to create & drop database
  • [Ecto.Changeset] Support action: :ignore in changeset which is useful when casting associations and embeds and one or more children need to be rejected/ignored under certain circumstances
  • [Ecto.Changeset] Add :repo_opts field to Ecto.Changeset which are given as options to to the repository whenever an operation is performed
  • [Ecto.Changeset] Add apply_action/2
  • [Ecto.Changeset] Add prefix constraint name checking to constraint validations
  • [Ecto.Changeset] Allow assocs and embeds in change/2 and put_change/3 - this gives a more generic API for developers to work that does not require explicit knowledge of the field type
  • [Ecto.Migration] Add reversible execute/2 to migrations
  • [Ecto.Migration] Add :migration_timestamps and :migration_primary_key to control the migration defaults from the repository
  • [Ecto.Migrator] Allow migration/rollback to log SQL commands via the --log-sql flag
  • [Ecto.LogEntry] Add :caller_pid to the Ecto.LogEntry struct
  • [Ecto.Query] Allow map updates in subqueries
  • [Ecto.Query] Support fragment and field access in type/2 in select
  • [Ecto.Query] Add select_merge/3 as a composable API for selects
  • [Ecto.Repo] Implement :returning option on insert
  • [Ecto.Repo] Add ON CONSTRAINT support to :conflict_target on insert and insert_all
  • [Ecto.Repo] Raise MultiplePrimaryKeyError when primary key is not unique on DB side
  • [Ecto.Schema] Validate schemas after compilation - this helps developers catch early mistakes such as foreign key mismatches early on
  • [Ecto.Type] Allow adapters to pass Date, Time, NaiveDateTime and DateTime on load if desired
  • [Ecto.UUID] Allow casting binary UUIDs
  • [mix ecto.drop] Add --force
  • [mix ecto.load] Add --force and prompt user to confirm before continuing in production

Bug fixes

  • [Ecto.Changeset] Remove the field from changes if it does not pass validate_required
  • [Ecto.Changeset] Raise if changeset struct does not match relation
  • [Ecto.Query] Consistently raise if nil is interpolated on the right side of in
  • [Ecto.Query] Properly expand macros in select
  • [Ecto.Query] Support or_having in keyword query
  • [Ecto.Query] Properly count the parameters when using interpolation inside a select inside a subquery
  • [Ecto.Repo] Set struct prefix on insert, delete, and update when the prefix is given as an option
  • [Ecto.UUID] Validate UUID version on casting
  • [mix ecto.*] Make sure Logger is rebootted when running ecto tasks
  • [mix ecto.*] No longer mark tasks as recursive and instead collect all repositories upfront. This fixes a bug where migration and rollback commands for a given repository could be executed multiple times from an umbrella project


  • [Ecto.DateTime] Ecto.DateTime as well as Ecto.Date and Ecto.Time are deprecated in favor of :naive_datetime, :date and :time respectively
  • [Ecto.Repo] Using {:system, env} to configure the repository URL is deprecated in favor of a custom init/2 callback

Previous versions


  • Also support Poison ~> 2.0

Bug fixes

  • Ensure optimistic_lock reads data from changes
  • Ensure BIT(1) type can be loaded as type :boolean for MYSQL
More projects by elixir-ecto View all
Other projects in Elixir