View Source Changelog for v3.x


v3.8.4 (2022-06-04)



  • [Ecto.Multi] Add one/2 and all/2 functions
  • [Ecto.Query] Support literal(...) in fragment


Bug fix

  • [Ecto.Schema] Make sure fields are inspected in the correct order in Elixir v1.14+


v3.8.3 (2022-05-11)


Bug fix

  • [Ecto.Query] Allow source aliases to be used in type/2
  • [Ecto.Schema] Avoid "undefined behaviour/struct" warnings and errors during compilation


v3.8.2 (2022-05-05)


Bug fix

  • [Ecto.Adapter] Do not require adapter metadata to be raw maps
  • [Ecto.Association] Respect join_where in many to many on_replace deletes
  • [Ecto.Changeset] Check if list is in empty_values before nested validations


v3.8.1 (2022-04-27)


Bug fix

  • [Ecto.Query] Fix regression where a join's on parameter on update_all was out of order


v3.8.0 (2022-04-26)

Ecto v3.8 requires Elixir v1.10+.



  • [Ecto] Add new Embedded chapter to Introductory guides
  • [Ecto.Changeset] Allow custom :error_key in unique_constraint
  • [Ecto.Changeset] Add :match option to all constraint functions
  • [Ecto.Query] Support dynamic aliases
  • [Ecto.Query] Allow using type/2 with virtual fields
  • [Ecto.Query] Suggest alternatives to inexistent fields in queries
  • [Ecto.Query] Support passing queries using subqueries to insert_all
  • [Ecto.Repo] Allow stacktrace: true so stacktraces are included in telemetry events and logs
  • [Ecto.Schema] Validate options given to schema fields


Bug fixes

  • [Ecto.Changeset] Address regression on validate_subset no longer working with custom array types
  • [Ecto.Changeset] Potentially breaking change: Detect empty_values inside lists when casting. This may cause issues if you were relying on the casting of empty values (by default, only "").
  • [Ecto.Query] Handle atom list sigils in select
  • [Ecto.Query] Improve tracking of select_merge inside subqueries
  • [Ecto.Repo] Properly handle literals in queries given to insert_all
  • [Ecto.Repo] Don't surface persisted data as changes on embed updates
  • [Ecto.Schema] Preserve parent prefix on join tables


v3.7.2 (2022-03-13)



  • [Ecto.Schema] Add option to skip validations for default values
  • [Ecto.Query] Allow coalesce in type/2
  • [Ecto.Query] Support parameterized types in type/2
  • [Ecto.Query] Allow arbitrary parentheses in query expressions


v3.7.1 (2021-08-27)



  • [Ecto.Embedded] Make Ecto.Embedded public and describe struct fields


Bug fixes

  • [Ecto.Repo] Make sure parent changeset is included in changes for insert/update/delete when there are errors processing the parent itself


v3.7.0 (2021-08-19)




Bug fixes

  • [Ecto.Changeset] Fix changeset inspection not redacting when embedded
  • [Ecto.Changeset] Use semantic comparison on validate_inclusion, validate_exclusion, and validate_subset
  • [Ecto.Enum] Raise on duplicate values in Ecto.Enum
  • [Ecto.Query] Make sure hints are included in the query cache
  • [Ecto.Repo] Support placeholders in insert_all without schemas
  • [Ecto.Repo] Wrap in a subquery when query given to Repo.aggregate has combination
  • [Ecto.Repo] Fix CTE subqueries not finding parent bindings
  • [Ecto.Repo] Return changeset with assocs if any of the assocs are invalid


v3.6.2 (2021-05-28)




Bug fixes

  • [Ecto.Query] Do not omit nil fields in a subquery select
  • [Ecto.Query] Allow parent_as to look for an alias all the way up across subqueries
  • [Ecto.Query] Raise if a nil value is given to a query from a nested map parameter
  • [Ecto.Query] Fix insert_all when using both :on_conflict and :placeholders
  • [mix ecto.load] Do not pass --force to underlying compile task


v3.6.1 (2021-04-12)



  • [Ecto.Changeset] Allow the :query option in unsafe_validate_unique


Bug fixes

  • [Ecto.Changeset] Add the relation id in apply_changes if the relation key exists (instead of hardcoding it to id)


v3.6.0 (2021-04-03)



  • [Ecto.Changeset] Support :repo_opts in unsafe_validate_unique
  • [Ecto.Changeset] Add a validation error if trying to cast a cardinality one embed/assoc with anything other than a map or keyword list
  • [Ecto.Enum] Allow enums to map to custom values
  • [Ecto.Multi] Add Ecto.Multi.put/3 for directly storing values
  • [Ecto.Query] Potentially breaking change: optimize many_to_many queries so it no longer load intermediary tables in more occasions. This may cause issues if you are using Ecto.assoc/2 to load many_to_many associations and then trying to access intermediate bindings (which is discouraged but it was possible)
  • [Ecto.Repo] Allow insert_all to be called with a query instead of rows
  • [Ecto.Repo] Add :placeholders support to insert_all to avoid sending the same value multiple times
  • [Ecto.Schema] Support :preload_order on has_many and many_to_many associations
  • [Ecto.UUID] Add bang UUID conversion methods
  • [Ecto.Query] The :hints option now accepts dynamic values when supplied as tuples
  • [Ecto.Query] Support select: map(source, fields) where source is a fragment
  • [Ecto.Query] Allow referring to the parent query in a join's subquery select via parent_as
  • [mix ecto] Support file and line interpolation on ECTO_EDITOR


Bug fixes

  • [Ecto.Changeset] Change apply_changes/1 to add the relation to the struct.relation_id if relation struct is persisted
  • [Ecto.Query] Remove unnecessary INNER JOIN in many to many association query
  • [Ecto.Query] Allow parametric types to be interpolated in queries
  • [Ecto.Schema] Raise ArgumentError when default has invalid type


v3.5.8 (2021-02-21)



  • [Ecto.Query] Support map/2 on fragments and subqueries


v3.5.7 (2021-02-07)


Bug fixes

  • [Ecto.Query] Fixes param ordering issue on dynamic queries with subqueries


v3.5.6 (2021-01-20)



  • [Ecto.Schema] Support on_replace: :delete_if_exists on associations


Bug fixes

  • [Ecto.Query] Allow unary minus operator in query expressions
  • [Ecto.Schema] Allow nil values on typed maps


v3.5.5 (2020-11-12)



  • [Ecto.Query] Add support for subqueries operators: all, any, and exists


Bug fixes

  • [Ecto.Changeset] Use association source on put_assoc with maps/keywords
  • [Ecto.Enum] Add cast clause for nil values on Ecto.Enum
  • [Ecto.Schema] Allow nested type :any for non-virtual fields


v3.5.4 (2020-10-28)



  • [mix ecto.drop] Provide --force-drop for databases that may support it
  • [guides] Add new "Multi tenancy with foreign keys" guide


Bug fixes

  • [Ecto.Changeset] Make keys optional in specs
  • [Ecto.Enum] Make sure values/2 works for virtual fields
  • [Ecto.Query] Fix missing type on CTE queries that select a single field


v3.5.3 (2020-10-21)


Bug fixes

  • [Ecto.Query] Do not reset parameter counter for nested CTEs
  • [Ecto.Type] Fix regression where array type with nils could no longer be cast/load/dump
  • [Ecto.Type] Fix CaseClauseError when casting a decimal with a binary remainder


v3.5.2 (2020-10-12)



  • [Ecto.Repo] Add Repo.reload/2 and Repo.reload!/2


Bug fixes

  • [Ecto.Changeset] Fix "schema/1 is undefined or private" error while inspecting a schemaless changeset
  • [Ecto.Repo] Invoke Ecto.Repo.default_options/1 per entry-point operation


v3.5.1 (2020-10-08)



  • [Ecto.Changeset] Warn if there are duplicate IDs in the parent schema for cast_assoc/3/cast_embed/3
  • [Ecto.Schema] Allow belongs_to to accept options for parameterized types


Bug fixes

  • [Ecto.Query] Keep field types when using a subquery with source


v3.5.0 (2020-10-03)

v3.5 requires Elixir v1.8+.


Bug fixes

  • [Ecto.Changeset] Ensure :empty_values in cast/4 does not automatically propagate to following cast calls. If you want a given set of :empty_values to apply to all cast/4 calls, change the value stored in changeset.empty_values instead
  • [Ecto.Changeset] Potentially breaking change: Do not force repository updates to happen when using optimistic_lock. The lock field will only be incremented if the record has other changes. If no changes, nothing happens.
  • [Ecto.Changeset] Do not automatically share empty values across cast/3 calls
  • [Ecto.Query] Consider query prefix in cte/combination query cache
  • [Ecto.Query] Allow the entry to be marked as nil when using left join with subqueries
  • [Ecto.Query] Support subqueries inside dynamic expressions
  • [Ecto.Repo] Fix preloading when using dynamic repos and the sandbox in automatic mode
  • [Ecto.Repo] Do not duplicate collections when associations are preloaded for repeated elements



  • [Ecto.Enum] Add Ecto.Enum as a custom parameterized type
  • [Ecto.Query] Allow :prefix in from to be set to nil
  • [Ecto.Query] Do not restrict subqueries in where to map/struct types
  • [Ecto.Query] Allow atoms in query without interpolation in order to support Ecto.Enum
  • [Ecto.Schema] Do not validate uniqueness if there is a prior error on the field
  • [Ecto.Schema] Allow redact: true in field
  • [Ecto.Schema] Support parameterized types via Ecto.ParameterizedType
  • [Ecto.Schema] Rewrite embeds and assocs as parameterized types. This means __schema__(:type, assoc_or_embed) now returns a parameterized type. To check if something is an association, use __schema__(:assocs) or __schema__(:embeds) instead


v3.4.6 (2020-08-07)



  • [Ecto.Query] Allow count/0 on type/2
  • [Ecto.Multi] Support anonymous functions in multiple functions


Bug fixes

  • [Ecto.Query] Consider booleans as literals in unions, subqueries, ctes, etc
  • [Ecto.Schema] Generate IDs for nested embeds


v3.4.5 (2020-06-14)



  • [Ecto.Changeset] Allow custom error key in unsafe_validate_unique
  • [Ecto.Changeset] Improve performance when casting large params maps


Bug fixes

  • [Ecto.Changeset] Improve error message for invalid cast_assoc
  • [Ecto.Query] Fix inspecting query with fragment CTE
  • [Ecto.Query] Fix inspecting dynamics with aliased bindings
  • [Ecto.Query] Improve error message when selecting a single atom
  • [Ecto.Repo] Reduce data-copying when preloading multiple associations
  • [Ecto.Schema] Do not define a compile-time dependency for schema in :join_through


v3.4.4 (2020-05-11)



  • [Ecto.Schema] Add join_where support to many_to_many


v3.4.3 (2020-04-27)



  • [Ecto.Query] Support as/1 and parent_as/1 for lazy named bindings and to allow parent references from subqueries
  • [Ecto.Query] Support x in subquery(query)


Bug fixes

  • [Ecto.Query] Do not raise for missing assocs if :force is given to preload
  • [Ecto.Repo] Return error from Repo.delete on invalid changeset from prepare_changeset


v3.4.2 (2020-04-10)



  • [Ecto.Changeset] Support multiple fields in unique_constraint/3


v3.4.1 (2020-04-08)




Bug fixes

  • [Ecto.Query] Do not support JSON selectors on type/2



  • [Ecto.Repo] Deprecate conflict_target: {:constraint, _}. It is a discouraged approach and {:unsafe_fragment, _} is still available if someone definitely needs it


v3.4.0 (2020-03-24)

v3.4 requires Elixir v1.7+.



  • [Ecto.Query] Allow dynamic queries in CTE and improve error message
  • [Ecto.Query] Add Ecto.Query.API.json_extract_path/2 and JSON path support to query syntax. For example, posts.metadata["tags"][0]["name"] will return the name of the first tag stored in the :map metadata field
  • [Ecto.Repo] Add new default_options/1 callback to repository
  • [Ecto.Repo] Support passing :telemetry_options to repository operations


Bug fixes

  • [Ecto.Changeset] Properly add validation annotation to validate_acceptance
  • [Ecto.Query] Raise if there is loaded non-empty association data without related key when preloading. This typically means not all fields have been loaded in a query
  • [Ecto.Schema] Show meaningful error in case schema is invoked twice in an Ecto.Schema


v3.3.4 (2020-02-27)


Bug fixes

  • [mix ecto] Do not rely on map ordering when parsing repos
  • [mix ecto.gen.repo] Improve error message when a repo is not given


v3.3.3 (2020-02-14)



  • [Ecto.Query] Support fragments in lock
  • [Ecto.Query] Handle nil in select_merge with similar semantics to SQL databases (i.e. it simply returns nil itself)


v3.3.2 (2020-01-28)



  • [Ecto.Changeset] Only bump optimistic lock in case of success
  • [Ecto.Query] Allow macros in Ecto window expressions
  • [Ecto.Schema] Support :join_defaults on many_to_many associations
  • [Ecto.Schema] Allow MFargs to be given to association :defaults
  • [Ecto.Type] Add Ecto.Type.embedded_load and Ecto.Type.embedded_dump


Bug fixes

  • [Ecto.Repo] Ignore empty hostname when parsing database url (Elixir v1.10 support)
  • [Ecto.Repo] Rewrite combinations on Repo.exists? queries
  • [Ecto.Schema] Respect child @schema_prefix in cast_assoc
  • [mix ecto.gen.repo] Use config_path when writing new config in mix ecto.gen.repo


v3.3.1 (2019-12-27)



  • [Ecto.Query.WindowAPI] Support filter/2


Bug fixes

  • [Ecto.Query.API] Fix coalesce/2 usage with mixed types


v3.3.0 (2019-12-11)



  • [Ecto.Adapter] Add storage_status/1 callback to Ecto.Adapters.Storage behaviour
  • [Ecto.Changeset] Add Ecto.Changeset.apply_action!/2
  • [Ecto.Changeset] Remove actions restriction in Ecto.Changeset.apply_action/2
  • [Ecto.Repo] Introduce c:Ecto.Repo.aggregate/2
  • [Ecto.Repo] Support {:replace_all_except, fields} in :on_conflict


Bug fixes

  • [Ecto.Query] Make sure the :prefix option in :from/:join also cascades to subqueries
  • [Ecto.Query] Make sure the :prefix option in :join also cascades to queries
  • [Ecto.Query] Use database returned values for literals. Previous Ecto versions knew literals from queries should not be discarded for combinations but, even if they were not discarded, we would ignore the values returned by the database
  • [Ecto.Repo] Do not wrap schema operations in a transaction if already inside a transaction. We have also removed the private option called :skip_transaction



  • [Ecto.Repo] :replace_all_except_primary_keys is deprecated in favor of {:replace_all_except, fields} in :on_conflict


v3.2.5 (2019-11-03)


Bug fixes

  • [Ecto.Query] Fix a bug where executing some queries would leak the {:maybe, ...} type


v3.2.4 (2019-11-02)


Bug fixes

  • [Ecto.Query] Improve error message on invalid join binding
  • [Ecto.Query] Make sure the :prefix option in :join also applies to through associations
  • [Ecto.Query] Invoke custom type when loading aggregations from the database (but fallback to database value if it can't be cast)
  • [mix ecto.gen.repo] Support Elixir v1.9 style configs


v3.2.3 (2019-10-17)


Bug fixes

  • [Ecto.Changeset] Do not convert enums given to validate_inclusion to a list



  • [Ecto.Changeset] Improve error message on non-atom keys to change/put_change
  • [Ecto.Changeset] Allow :with to be given as a {module, function, args} tuple on cast_association/cast_embed
  • [Ecto.Changeset] Add fetch_change!/2 and fetch_field!/2


v3.2.2 (2019-10-01)


Bug fixes

  • [Ecto.Query] Fix keyword arguments given to :on when a bind is not given to join
  • [Ecto.Repo] Make sure a preload given to an already preloaded has_many :through is loaded


v3.2.1 (2019-09-17)



  • [Ecto.Changeset] Add rollover logic for default incrementer in optimistic_lock
  • [Ecto.Query] Also expand macros when used inside type/2


Bug fixes

  • [Ecto.Query] Ensure queries with non-cacheable queries in CTEs/combinations are also not-cacheable


v3.2.0 (2019-09-07)

v3.2 requires Elixir v1.6+.



  • [Ecto.Query] Add common table expressions support with_cte/3 and recursive_ctes/2
  • [Ecto.Query] Allow dynamic/3 to be used in order_by, distinct, group_by, as well as in partition_by, order_by, and frame inside windows
  • [Ecto.Query] Allow filters in type/2 expressions
  • [Ecto.Repo] Merge options given to the repository into the changeset repo_opts and assign it back to make it available down the chain
  • [Ecto.Repo] Add prepare_query/3 callback that is invoked before query operations
  • [Ecto.Repo] Support :returning option in Ecto.Repo.update/2
  • [Ecto.Repo] Support passing a one arity function to Ecto.Repo.transaction/2, where the argument is the current repo
  • [Ecto.Type] Add a new embed_as/1 callback to Ecto.Type that allows adapters to control embedding behaviour
  • [Ecto.Type] Add use Ecto.Type for convenience that implements the new required callbacks


Bug fixes

  • [Ecto.Association] Ensure we delete an association before inserting when replacing on has_one
  • [Ecto.Query] Do not allow interpolated nil in literal keyword list when building query
  • [Ecto.Query] Do not remove literals from combinations, otherwise UNION/INTERSECTION queries may not match the number of values in select
  • [Ecto.Query] Do not attempt to merge at compile-time non-keyword lists given to select_merge
  • [Ecto.Repo] Do not override :through associations on preload unless forcing
  • [Ecto.Repo] Make sure prefix option cascades to combinations and recursive queries
  • [Ecto.Schema] Use OS time without drift when generating timestamps
  • [Ecto.Type] Allow any datetime in datetime_add


v3.1.7 (2019-06-27)


Bug fixes

  • [Ecto.Changeset] Make sure put_assoc with empty changeset propagates on insert


v3.1.6 (2019-06-19)



  • [Ecto.Repo] Add :read_only repositories
  • [Ecto.Schema] Also validate options given to :through associations


Bug fixes

  • [Ecto.Changeset] Do not mark put_assoc from [] to [] or from nil to nil as change
  • [Ecto.Query] Remove named binding when excluding joins
  • [mix ecto.gen.repo] Use :config_path instead of hardcoding to config/config.exs


v3.1.5 (2019-06-06)



  • [Ecto.Repo] Allow :default_dynamic_repo option on use Ecto.Repo
  • [Ecto.Schema] Support {:fragment, ...} in the :where option for associations


Bug fixes

  • [Ecto.Query] Fix handling of literals in combinators (union, except, intersection)


v3.1.4 (2019-05-07)


Bug fixes

  • [Ecto.Changeset] Convert validation enums to lists before adding them as validation metadata
  • [Ecto.Schema] Properly propagate prefix to join_through source in many_to_many associations


v3.1.3 (2019-04-30)



  • [Ecto.Changeset] Expose the enum that was validated against in errors from enum-based validations


v3.1.2 (2019-04-24)



  • [Ecto.Query] Add support for type+over
  • [Ecto.Schema] Allow schema fields to be excluded from queries


Bug fixes

  • [Ecto.Changeset] Do not list a field as changed if it is updated to its original value
  • [Ecto.Query] Keep literal numbers and bitstring in subqueries and unions
  • [Ecto.Query] Improve error message for invalid type/2 expression
  • [Ecto.Query] Properly count interpolations in select_merge/2


v3.1.1 (2019-04-04)


Bug fixes

  • [Ecto] Do not require Jason (i.e. it should continue to be an optional dependency)
  • [Ecto.Repo] Make sure many_to_many and Ecto.Multi work with dynamic repos


v3.1.0 (2019-04-02)

v3.1 requires Elixir v1.5+.



  • [Ecto.Changeset] Add not_equal_to option for validate_number
  • [Ecto.Query] Improve error message for missing fragment arguments
  • [Ecto.Query] Improve error message on missing struct key for structs built in select
  • [Ecto.Query] Allow dynamic named bindings
  • [Ecto.Repo] Add dynamic repository support with Ecto.Repo.put_dynamic_repo/1 and Ecto.Repo.get_dynamic_repo/0 (experimental)
  • [Ecto.Type] Cast naive_datetime/utc_datetime strings without seconds


Bug fixes

  • [Ecto.Changeset] Do not run unsafe_validate_unique query unless relevant fields were changed
  • [Ecto.Changeset] Raise if an unknown field is given on Ecto.Changeset.change/2
  • [Ecto.Changeset] Expose the type that was validated in errors generated by validate_length/3
  • [Ecto.Query] Add support for field/2 as first element of type/2 and alias as second element of type/2
  • [Ecto.Query] Do not attempt to assert types of named bindings that are not known at compile time
  • [Ecto.Query] Properly cast boolean expressions in select
  • [Mix.Ecto] Load applications during repo lookup so their app environment is available



  • [Ecto.LogEntry] Fully deprecate previously soft deprecated API


v3.0.7 (2019-02-06)


Bug fixes

  • [Ecto.Query] reverse_order reverses by primary key if no order is given


v3.0.6 (2018-12-31)



  • [Ecto.Query] Add reverse_order/1


Bug fixes

  • [Ecto.Multi] Raise better error message on accidental rollback inside Ecto.Multi
  • [Ecto.Query] Properly merge deeply nested preloaded joins
  • [Ecto.Query] Raise better error message on missing select on schemaless queries
  • [Ecto.Schema] Fix parameter ordering in assoc :where


v3.0.5 (2018-12-08)


Backwards incompatible changes

  • [Ecto.Schema] The :where option added in Ecto 3.0.0 had a major flaw and it has been reworked in this version. This means a tuple of three elements can no longer be passed to :where, instead a keyword list must be given. Check the "Filtering associations" section in has_many/3 docs for more information


Bug fixes

  • [Ecto.Query] Do not raise on lists of tuples that are not keywords. Instead, let custom Ecto.Type handle them
  • [Ecto.Query] Allow prefix: nil to be given to subqueries
  • [Ecto.Query] Use different cache keys for unions/intersections/excepts
  • [Ecto.Repo] Fix support for upserts with :replace without a schema
  • [Ecto.Type] Do not lose precision when casting utc_datetime_usec with a time zone different than Etc/UTC


v3.0.4 (2018-11-29)



  • [Decimal] Bump decimal dependency
  • [Ecto.Repo] Remove unused :pool_timeout


v3.0.3 (2018-11-20)



  • [Ecto.Changeset] Add count: :bytes option in validate_length/3
  • [Ecto.Query] Support passing Ecto.Query in Ecto.Repo.insert_all


Bug fixes

  • [Ecto.Type] Respect adapter types when loading/dumping arrays and maps
  • [Ecto.Query] Ensure no bindings in order_by when using combinations in Ecto.Query
  • [Ecto.Repo] Ensure adapter is compiled (instead of only loaded) before invoking it
  • [Ecto.Repo] Support new style child spec from adapters


v3.0.2 (2018-11-17)


Bug fixes

  • [Ecto.LogEntry] Bring old Ecto.LogEntry APIs back for compatibility
  • [Ecto.Repo] Consider non-joined fields when merging preloaded assocs only at root
  • [Ecto.Repo] Take field sources into account in :replace_all_fields upsert option
  • [Ecto.Type] Convert :utc_datetime to DateTime when sending it to adapters


v3.0.1 (2018-11-03)


Bug fixes

  • [Ecto.Query] Ensure parameter order is preserved when using more than 32 parameters
  • [Ecto.Query] Consider query prefix when planning association joins
  • [Ecto.Repo] Consider non-joined fields as unique parameters when merging preloaded query assocs


v3.0.0 (2018-10-29)

Note this version includes changes from ecto and ecto_sql but in future releases all ecto_sql entries will be listed in their own CHANGELOG.



  • [Ecto.Adapters.MySQL] Add ability to specify cli_protocol for ecto.create and ecto.drop commands
  • [Ecto.Adapters.PostgreSQL] Add ability to specify maintenance database name for PostgreSQL adapter for ecto.create and ecto.drop commands
  • [Ecto.Changeset] Store constraint name in error metadata for constraints
  • [Ecto.Changeset] Add validations/1 and constraints/1 instead of allowing direct access on the struct fields
  • [Ecto.Changeset] Add :force_update option when casting relations, to force an update even if there are no changes
  • [Ecto.Migration] Migrations now lock the migrations table in order to avoid concurrent migrations in a cluster. The type of lock can be configured via the :migration_lock repository configuration and defaults to "FOR UPDATE" or disabled if set to nil
  • [Ecto.Migration] Add :migration_default_prefix repository configuration
  • [Ecto.Migration] Add reversible version of remove/2 subcommand
  • [Ecto.Migration] Add support for non-empty arrays as defaults in migrations
  • [Ecto.Migration] Add support for logging notices/alerts/warnings when running migrations (only supported by Postgres currently)
  • [Ecto.Migrator] Warn when migrating and there is a higher version already migrated in the database
  • [Ecto.Multi] Add support for anonymous functions in insert/4, update/4, insert_or_update/4, and delete/4
  • [Ecto.Query] Support tuples in where and having, allowing queries such as where: {,} > {^foo, ^bar}
  • [Ecto.Query] Support arithmetic operators in queries as a thin layer around the DB functionality
  • [Ecto.Query] Allow joins in queries to be named via :as and allow named bindings
  • [Ecto.Query] Support excluding specific join types in exclude/2
  • [Ecto.Query] Allow virtual field update in subqueries
  • [Ecto.Query] Support coalesce/2 in queries, such as select: coalesce(p.title, p.old_title)
  • [Ecto.Query] Support filter/2 in queries, such as select: filter(count(, p.public == true)
  • [Ecto.Query] The :prefix and :hints options are now supported on both from and join expressions
  • [Ecto.Query] Support :asc_nulls_last, :asc_nulls_first, :desc_nulls_last, and :desc_nulls_first in order_by
  • [Ecto.Query] Allow variables (sources) to be given in queries, for example, useful for invoking functions, such as fragment("some_function(?)", p)
  • [Ecto.Query] Add support for union, union_all, intersection, intersection_all, except and except_all
  • [Ecto.Query] Add support for windows and over
  • [Ecto.Query] Raise when comparing a string with a charlist during planning
  • [Ecto.Repo] Only start transactions if an association or embed has changed, this reduces the overhead during repository operations
  • [Ecto.Repo] Support :replace_all_except_primary_key as :on_conflict strategy
  • [Ecto.Repo] Support {:replace, fields} as :on_conflict strategy
  • [Ecto.Repo] Support :unsafe_fragment as :conflict_target
  • [Ecto.Repo] Support select in queries given to update_all and delete_all
  • [Ecto.Repo] Add Repo.exists?/2
  • [Ecto.Repo] Add Repo.checkout/2 - useful when performing multiple operations in short-time to interval, allowing the pool to be bypassed
  • [Ecto.Repo] Add :stale_error_field to Repo.insert/update/delete that converts Ecto.StaleEntryError into a changeset error. The message can also be set with :stale_error_message
  • [Ecto.Repo] Preloading now only sorts results by the relationship key instead of sorting by the whole struct
  • [Ecto.Schema] Allow :where option to be given to has_many/has_one/belongs_to/many_to_many


Bug fixes

  • [Ecto.Inspect] Do not fail when inspecting query expressions which have a number of bindings more than bindings available
  • [Ecto.Migration] Keep double underscores on autogenerated index names to be consistent with changesets
  • [Ecto.Query] Fix for single nil column with join
  • [Ecto.Migration] Ensure create_if_not_exists is properly reversible
  • [Ecto.Repo] Allow many_to_many associations to be preloaded via a function (before the behaviour was erratic)
  • [Ecto.Schema] Make autogen ID loading work with custom type
  • [Ecto.Schema] Make updated_at have the same value as inserted_at
  • [Ecto.Schema] Ensure all fields are replaced with on_conflict: :replace_all/:replace_all_except_primary_key and not only the fields sent as changes
  • [Ecto.Type] Return :error when casting NaN or infinite decimals
  • [mix ecto.migrate] Properly run migrations after ECTO_EDITOR changes
  • [mix ecto.migrations] List migrated versions even if the migration file is deleted
  • [mix ecto.load] The task now fails on SQL errors on Postgres



Although Ecto 3.0 is a major bump version, the functionality below emits deprecation warnings to ease the migration process. The functionality below will be removed in future Ecto 3.1+ releases.

  • [Ecto.Changeset] Passing a list of binaries to cast/3 is deprecated, please pass a list of atoms instead
  • [Ecto.Multi] now receives the repo in which the transaction is executing as the first argument to functions, and the changes so far as the second argument
  • [Ecto.Query] join/5 now expects on: expr as last argument instead of simply expr. This was done in order to properly support the :as, :hints and :prefix options
  • [Ecto.Repo] The :returning option for update_all and delete_all has been deprecated as those statements now support select clauses
  • [Ecto.Repo] Passing :adapter via config is deprecated in favor of passing it on use Ecto.Repo
  • [Ecto.Repo] The :loggers configuration is deprecated in favor of "Telemetry Events"


Backwards incompatible changes

  • [Ecto.DateTime] Ecto.Date, Ecto.Time and Ecto.DateTime were previously deprecated and have now been removed
  • [Ecto.DataType] Ecto.DataType protocol has been removed
  • [Ecto.Migration] Automatically inferred index names may differ in Ecto v3.0 for indexes on complex column names
  • [Ecto.Multi] now receives the repo in which the transaction is executing as the first argument to functions, and the changes so far as the second argument
  • [Ecto.Query] A join no longer wraps fragment in parentheses. In some cases, such as common table expressions, you will have to explicitly wrap the fragment in parens.
  • [Ecto.Repo] The on_conflict: :replace_all option now will also send fields with default values to the database. If you prefer the old behaviour that only sends the changes in the changeset, you can set it to on_conflict: {:replace, Map.keys(changeset.changes)} (this change is also listed as a bug fix)
  • [Ecto.Repo] The repository operations are no longer called from association callbacks - this behaviour was not guaranteed in previous versions but we are listing as backwards incompatible changes to help with users relying on this behaviour
  • [Ecto.Repo] :pool_timeout is no longer supported in favor of a new queue system described in DBConnection.start_link/2 under "Queue config". For most users, configuring :timeout is enough, as it now includes both queue and query time
  • [Ecto.Schema] :time, :naive_datetime and :utc_datetime no longer keep microseconds information. If you want to keep microseconds, use :time_usec, :naive_datetime_usec, :utc_datetime_usec
  • [Ecto.Schema] The @schema_prefix option now only affects the from/join of where the schema is used and no longer the whole query
  • [Ecto.Schema.Metadata] The source key no longer returns a tuple of the schema_prefix and the table/collection name. It now returns just the table/collection string. You can now access the schema_prefix via the prefix key.
  • [Mix.Ecto] Mix.Ecto.ensure_started/2 has been removed. However, in Ecto 2.2 the Mix.Ecto module was not considered part of the public API and should not have been used but we are listing this for guidance.


Adapter changes

  • [Ecto.Adapter] Split Ecto.Adapter into Ecto.Adapter.Queryable and Ecto.Adapter.Schema to provide more granular repository APIs
  • [Ecto.Adapter] The :sources field in query_meta now contains three elements tuples with {source, schema, prefix} in order to support from/join prefixes (#2572)
  • [Ecto.Adapter] The database types time, utc_datetime and naive_datetime should translate to types with seconds precision while the database types time_usec, utc_datetime_usec and naive_datetime_usec should have microseconds precision (#2291)
  • [Ecto.Adapter] The on_conflict argument for insert and insert_all no longer receives a {:replace_all, list(), atom()} tuple. Instead, it receives a {fields :: [atom()], list(), atom()} where fields is a list of atoms of the fields to be replaced (#2181)
  • [Ecto.Adapter] insert/update/delete now receive both :source and :prefix fields instead of a single :source field with both source and prefix in it (#2490)
  • [Ecto.Adapter.Migration] A new lock_for_migration/4 callback has been added. It is implemented by default by Ecto.Adapters.SQL (#2215)
  • [Ecto.Adapter.Migration] The execute_ddl should now return {:ok, []} to make space for returning notices/hints/warnings in the future (adapters leveraging Ecto.Adapters.SQL do not have to perform any change)
  • [Ecto.Query] The from field in Ecto.Query now returns a Ecto.Query.FromExpr with the :source field, unifying the behaviour in from and join expressions (#2497)
  • [Ecto.Query] Tuple expressions are now supported in queries. For example, where: {,} > {, p.baz} should translate to WHERE (, > (, p.baz) in SQL databases. Adapters should be changed to handle {:{}, meta, exprs} in the query AST (#2344)
  • [Ecto.Query] Adapters should support the following arithmetic operators in queries +, -, * and / (#2400)
  • [Ecto.Query] Adapters should support filter/2 in queries, as in select: filter(count(, p.public == true) (#2487)


Previous versions