- [Ecto.Repo] Use
persistent_term
for faster repository lookup - [Ecto.Repo] Document new
:pool_count
option
- [Ecto.Repo] Make
Ecto.Repo.reload
respectsource
- [Ecto.Changeset] Allow associations to be cast/put inside of embedded schema changesets
- [Ecto.Query] Allow
:prefix
to be set to any term - [Ecto.Repo] Avoid overwriting ssl opts from url if already set in config
- [Ecto.Type] Add
Ecto.Type.parameterized?/2
- [Ecto.Enum] Fix dialyzer specification
- [Ecto.Query] Remove incorrect subquery parameter check
- [Ecto.Changeset] Allow
{message, opts}
to be given as message for several validation APIs - [Ecto.Query] Introduce
is_named_binding
guard - [Ecto.Query] Subqueries are now supported in
distinct
,group_by
,order_by
andwindow
expressions - [Ecto.Query] Allow
select_merge
to be used in moreinsert_all
and subquery operations by merging distinct fields - [Ecto.Query] Allow literal maps inside
dynamic/2
- [Ecto.Query] Support macro expansion at the root level of
order_by
- [Ecto.Query] Support preloading subquery sources in
from
andjoin
- [Ecto.Query] Allow map updates with dynamic values in
select
- [Ecto.Query] Allow any data structure that implements the Enumerable protocol on the right side of
in
- [Ecto.Repo] Support 2-arity preload functions that receive ids and the association metadata
- [Ecto.Repo] Allow Hot Updates on upsert queries in Postgres by removing duplicate fields during replace_all
- [Ecto.Repo]
insert_all
supports queries with only source - [Ecto.Repo]
insert_all
supports queries with the update syntax - [Ecto.Repo] Support
:allow_stale
on Repo struct/changeset operations - [Ecto.Schema] Allow schema fields to be read-only via
:writable
option - [Ecto.Schema] Add
:defaults_to_struct
option toembeds_one
- [Ecto.Schema] Support
:duration
type which maps to Elixir v1.17 duration - [Ecto.Type] Bubble up custom cast errors of the inner type for
{:map, type}
and{:array, type}
- [Ecto.Type] Add
Ecto.Type.cast!/2
- [Ecto.Query] Ignore query prefix in CTE sources
- [Ecto.Query] Fix a bug of
preload
when a through association is used in a join and has a nested separate query preload. Now the association chain is no longer preloaded and we simply preload directly onto the loaded through association. - [Ecto.Query] Fix inspection when select has
map/struct
modifiers - [Ecto.Query] Disable query cache for
values
lists - [Ecto.Repo] Convert fields to their sources in
insert_all
- [Ecto.Repo] Raise if empty list is given to
{:replace, fields}
- [Ecto.Repo] Validate
:prefix
is a string/binary, warn otherwise - [Ecto.Repo] Remove compile dependency on
:preload_order
MFA inhas_many
distinct
,group_by
,order_by
andwindow
expressions use the newEcto.Query.ByExpr
struct rather than the oldEcto.Query.QueryExpr
struct
- [Ecto.Changeset] Associations inside embeds have always been read-only. We now raise if you try to cast them inside a changeset (this was reverted in v3.12.3)
- [Ecto.ParameterizedType] Parameterized types are now represented internally as
{:parameterized, {mod, state}}
. While this representation is private, projects may have been relying on it, and therefore they need to adapt accordingly. UseEcto.ParameterizedType.init/2
to instantiate parameterized types. - [Ecto.Query] Drop
:array_join
join type. It was added for Clickhouse support but it is no longer used - [Ecto.Query] Validate
:prefix
is a string/binary (this was reverted in v3.12.2)
- [Ecto.Query] Fix compatibility with upcoming Elixir v1.17
- [Ecto.Repo] Do not hide failures when preloading if the parent process is trapping exits
- [Ecto.Query] Allow module attributes to be given to
in
operator
- [Ecto.Query] Fix interpolating strings and atoms as map keys
- [Ecto.Query] Plan subqueries in
having
- [Ecto.Query] Fix late binding with composite types
- [Ecto.Association] Allow
preload_order
to take MFAs formany_to_many
associations. This allows ordering by the join table - [Ecto.Query] Add
:operation
option towith_cte/3
. This allows CTEs to perform updates and deletes - [Ecto.Query] Support
splice(^...)
infragment
- [Ecto.Query] Add
prepend_order_by/3
- [Ecto.Query] Allow
selected_as/1
andselected_as/2
to take interpolated names - [Ecto.Query] Allow map update syntax to work with
nil
values inselect
- [Ecto.Query] Allow hints to inject SQL using
unsafe_fragment
- [Ecto.Query] Support
values/2
lists - [Ecto.Repo] Add
:on_preload_spawn
option topreload/3
- [Ecto.Schema] Support
:load_in_query
option for embeds - [Ecto.Schema] Support
:returning
option for delete
- [Ecto.Association] Ensure parent prefix is passed to
on_delete
queries - [Ecto.Changeset] Ensure duplicate primary keys are always detected for embeds
- [Ecto.Embedded] Raise
ArgumentError
when specifying an autogenerated:id
primary key - [Ecto.Query] Ensure subquery selects generate unique cache keys
- [Ecto.Query] Raise on literal non-base binary/uuids in query
- [Ecto.Repo] Reset
belongs_to
association if foreign key update results in a mismatch
- Adapters now receive
nil
for encoding/decoding - Adapters now receive
type
instead of{:maybe, type}
as the first argument toloaders/2
- [Ecto.Query] Keyword hints are no longer supported. Please use
unsafe_fragment
inside of hints instead
- [Ecto.Query] Allow dynamic
field/2
intype/2
- [Ecto.Changesets] Limit the largest integer to less than 32 digits
- [Ecto.Type] Limit the largest integer to less than 32 digits
- [Ecto.Changeset] Support a three-arity function with position on
cast_assoc
andcast_embed
- [Ecto.Changeset] Add support for maps in
validate_length/3
- [Ecto.Changeset] Add
:nulls_distinct
option tounsafe_validate_unique
- [Ecto.Query] Support
array_join
type for ClickHouse adapter - [Ecto.Query.API] Support parameterized and custom map types in json path validation
- [Ecto.Repo] Respect parent prefix in
Repo.aggregate
- [Ecto.Query.API] Fix late binding in
json_extract_path
- Deprecate MFAs on
:with
- [Ecto.Changeset] Consider
sort_param
even if the relation param was not given - [Ecto.Query] Correct typespec to avoid Dialyzer warnings
This release contains many improvements to Ecto.Changeset, functions like Ecto.Changeset.changed?/2
and field_missing?/2
will help make your code more expressive. Improvements to association and embed handling will also make it easier to manage more complex forms, especially those embedded within Phoenix.LiveView applications.
On the changeset front, note this release unifies the handling of empty values between cast/4
and validate_required/3
. If you were setting :empty_values
in the past and you want to preserve this new behaviour throughout, you may want to update your code from this:
Ecto.Changeset.cast(changeset, params, [:field1, :field2], empty_values: ["", []])
to:
empty_values = [[]] ++ Ecto.Changeset.empty_values()
Ecto.Changeset.cast(changeset, params, [:field1, :field2], empty_values: empty_values)
Queries have also been improved to support LIMIT WITH TIES as well as materialized CTEs.
- [Ecto.Changeset] Add
get_assoc
/get_embed
- [Ecto.Changeset] Add
field_missing?/2
- [Ecto.Changeset] Add
changed?/2
andchanged?/3
with predicates support - [Ecto.Changeset] Allow
Regex
to be used in constraint names for exact matches - [Ecto.Changeset] Allow
:empty_values
option incast/4
to include a function which must return true if the value is empty - [Ecto.Changeset]
cast/4
will by default consider strings made only of whitespace characters to be empty - [Ecto.Changeset] Add support for
:sort_param
and:drop_param
oncast_assoc
andcast_embed
- [Ecto.Query] Support materialized option in CTEs
- [Ecto.Query] Support dynamic field inside
json_extract_path
- [Ecto.Query] Support interpolated values for from/join prefixes
- [Ecto.Query] Support ties in limit expressions through
with_ties/3
- [Ecto.Schema] Add
:autogenerate_fields
to the schema reflection API - [Ecto.ParameterizedType] Add optional callback
format/1
- [Ecto.Changeset] Make unsafe validate unique exclude primary key only for loaded schemas
- [Ecto.Changeset] Raise when change provided to
validate_format/4
is not a string - [Ecto.Query] Fix bug in
json_extract_path
where maps were not allowed to be nested inside of embeds - [Ecto.Schema] Allow inline embeds to overwrite conflicting aliases
- [Ecto.Query] Allow dynamic
field/2
intype/2
- [Ecto.Changesets] Limit the largest integer to less than 32 digits
- [Ecto.Type] Limit the largest integer to less than 32 digits
- [Ecto.Query] Rename
@opaque dynamic
type to@opaque dynamic_expr
to avoid conflicts with Erlang/OTP 26
- [Ecto.Query] Fix regression with interpolated preloads introduced in v3.9.3
- [Ecto] Add
reset_fields/2
- [Ecto.Multi] Add
exists?/4
function - [Ecto.Repo] Keep url scheme in the repo configuration
- [Ecto.Query] Add support for cross lateral joins
- [Ecto.Query] Allow preloads to use
dynamic/2
- [Ecto.Query.API] Allow the entire path to be interpolated in
json_extract_path/2
- [Ecto.Query] Allow
selected_as
inside CTE - [Ecto.Query] Allow
selected_as
to be used in subquery
- [Ecto.Repo] Fix preloading through associations on
nil
- [Ecto.Query] Fix select merging a
selected_as
field into a source
- [Ecto.Query] Allow
selected_as
at the root ofdynamic/2
- [Ecto.Query] Allow
selected_as
to be used withtype/2
- [Ecto.Query] Allow
selected_as
to be used withselect_merge
- [Ecto.Changeset] Reenable support for embedded schemas in
unsafe_validate_unique/4
- [Ecto.Query] Ensure
join_where
conditions preload correctly inmany_to_many
or with queries with one or many joins
- [Ecto.Changeset] Add
:force_changes
option tocast/4
- [Ecto.Enum] Allow enum fields to be embed either as their values or their dumped versions
- [Ecto.Query] Support
^%{field: dynamic(...)}
inselect
andselect_merge
- [Ecto.Query] Support
%{field: subquery(...)}
inselect
andselect_merge
- [Ecto.Query] Support select aliases through
selected_as/1
andselected_as/2
- [Ecto.Query] Allow
parent_as/1
intype/2
- [Ecto.Query] Add
with_named_binding/3
- [Ecto.Query] Allow fragment sources in keyword queries
- [Ecto.Repo] Support
idle_interval
query parameter in connection URL - [Ecto.Repo] Log human-readable UUIDs by using pre-dumped query parameters
- [Ecto.Schema] Support preloading associations in embedded schemas
- [Ecto.Changeset] Raise when schemaless changeset or embedded schema is used in
unsafe_validate_unique/4
- [Ecto.Query] Respect virtual field type in subqueries
- [Ecto.Query] Don't select struct fields overridden with
nil
- [Ecto.Query] Fix
select_merge
not trackingload_in_query: false
field - [Ecto.Query] Fix field source when used in
json_extract_path
- [Ecto.Query] Properly build CTEs at compile time
- [Ecto.Query] Properly order subqueries in
dynamic
- [Ecto.Repo] Fix
insert_all
query parameter count when using value queries alongsideplaceholder
- [Ecto.Repo] Raise if combination query is used in a
many
preload - [Ecto.Schema] Ignore associations that aren't loaded on insert
- [Ecto.Multi] Add
one/2
andall/2
functions - [Ecto.Query] Support
literal(...)
infragment
- [Ecto.Schema] Make sure fields are inspected in the correct order in Elixir v1.14+
- [Ecto.Query] Allow source aliases to be used in
type/2
- [Ecto.Schema] Avoid "undefined behaviour/struct" warnings and errors during compilation
- [Ecto.Adapter] Do not require adapter metadata to be raw maps
- [Ecto.Association] Respect
join_where
in many to manyon_replace
deletes - [Ecto.Changeset] Check if list is in
empty_values
before nested validations
- [Ecto.Query] Fix regression where a join's on parameter on
update_all
was out of order
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
- [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.Repo] Potentially breaking change: Raise if an association doesn't have a primary key and is preloaded in a join query. Previously, this would silently produce the wrong the result in certain circumstances.
- [Ecto.Schema] Preserve parent prefix on join tables
- [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
- [Ecto.Embedded] Make
Ecto.Embedded
public and describe struct fields
- [Ecto.Repo] Make sure parent changeset is included in changes for
insert
/update
/delete
when there are errors processing the parent itself
- [Ecto.Changeset] Add
Ecto.Changeset.traverse_validations/2
- [Ecto.Enum] Add
Ecto.Enum.mappings/2
andEcto.Enum.dump_values/2
- [Ecto.Query] Add support for dynamic
as(^as)
andparent_as(^as)
- [Ecto.Repo] Add stale changeset to
Ecto.StaleEntryError
fields - [Ecto.Schema] Add support for
@schema_context
to set context metadata on schema definition
- [Ecto.Changeset] Fix changeset inspection not redacting when embedded
- [Ecto.Changeset] Use semantic comparison on
validate_inclusion
,validate_exclusion
, andvalidate_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
- [Ecto.Query] Support macros in
with_cte
- [Ecto.Repo] Add
Ecto.Repo.all_running/0
to list all running repos
- [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
- [Ecto.Changeset] Allow the
:query
option inunsafe_validate_unique
- [Ecto.Changeset] Add the relation id in
apply_changes
if the relation key exists (instead of hardcoding it toid
)
- [Ecto.Changeset] Support
:repo_opts
inunsafe_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 usingEcto.assoc/2
to loadmany_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 toinsert_all
to avoid sending the same value multiple times - [Ecto.Schema] Support
:preload_order
onhas_many
andmany_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)
wheresource
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
- [Ecto.Changeset] Change
apply_changes/1
to add the relation to thestruct.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
- [Ecto.Query] Support map/2 on fragments and subqueries
- [Ecto.Query] Fixes param ordering issue on dynamic queries with subqueries
- [Ecto.Schema] Support
on_replace: :delete_if_exists
on associations
- [Ecto.Query] Allow unary minus operator in query expressions
- [Ecto.Schema] Allow nil values on typed maps
- [Ecto.Query] Add support for subqueries operators:
all
,any
, andexists
- [Ecto.Changeset] Use association source on
put_assoc
with maps/keywords - [Ecto.Enum] Add
cast
clause for nil values onEcto.Enum
- [Ecto.Schema] Allow nested type
:any
for non-virtual fields
- [mix ecto.drop] Provide
--force-drop
for databases that may support it - [guides] Add new "Multi tenancy with foreign keys" guide
- [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
- [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
- [Ecto.Repo] Add Repo.reload/2 and Repo.reload!/2
- [Ecto.Changeset] Fix "schema/1 is undefined or private" error while inspecting a schemaless changeset
- [Ecto.Repo] Invoke
c:Ecto.Repo.default_options/1
per entry-point operation
- [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
- [Ecto.Query] Keep field types when using a subquery with source
v3.5 requires Elixir v1.8+.
- [Ecto.Changeset] Ensure
:empty_values
incast/4
does not automatically propagate to following cast calls. If you want a given set of:empty_values
to apply to allcast/4
calls, change the value stored inchangeset.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
infrom
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
infield
- [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
- [Ecto.Query] Allow
count/0
ontype/2
- [Ecto.Multi] Support anonymous functions in multiple functions
- [Ecto.Query] Consider booleans as literals in unions, subqueries, ctes, etc
- [Ecto.Schema] Generate IDs for nested embeds
- [Ecto.Changeset] Allow custom error key in
unsafe_validate_unique
- [Ecto.Changeset] Improve performance when casting large params maps
- [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
- [Ecto.Schema] Add
join_where
support tomany_to_many
- [Ecto.Query] Support
as/1
andparent_as/1
for lazy named bindings and to allow parent references from subqueries - [Ecto.Query] Support
x in subquery(query)
- [Ecto.Query] Do not raise for missing assocs if :force is given to preload
- [Ecto.Repo] Return error from
Repo.delete
on invalid changeset fromprepare_changeset
- [Ecto.Changeset] Support multiple fields in
unique_constraint/3
- [Ecto] Add
Ecto.embedded_load/3
andEcto.embedded_dump/2
- [Ecto.Query] Improve error message on invalid JSON expressions
- [Ecto.Repo] Emit
[:ecto, :repo, :init]
telemetry event upon Repo init
- [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 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
- [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 anEcto.Schema
- [mix ecto] Do not rely on map ordering when parsing repos
- [mix ecto.gen.repo] Improve error message when a repo is not given
- [Ecto.Query] Support fragments in
lock
- [Ecto.Query] Handle
nil
inselect_merge
with similar semantics to SQL databases (i.e. it simply returnsnil
itself)
- [Ecto.Changeset] Only bump optimistic lock in case of success
- [Ecto.Query] Allow macros in Ecto window expressions
- [Ecto.Schema] Support
:join_defaults
onmany_to_many
associations - [Ecto.Schema] Allow MFargs to be given to association
:defaults
- [Ecto.Type] Add
Ecto.Type.embedded_load
andEcto.Type.embedded_dump
- [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
incast_assoc
- [mix ecto.gen.repo] Use
config_path
when writing new config inmix ecto.gen.repo
- [Ecto.Query.WindowAPI] Support
filter/2
- [Ecto.Query.API] Fix
coalesce/2
usage with mixed types
- [Ecto.Adapter] Add
storage_status/1
callback toEcto.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
- [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
- [Ecto.Query] Fix a bug where executing some queries would leak the
{:maybe, ...}
type
- [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
- [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 oncast_association/cast_embed
- [Ecto.Changeset] Add
fetch_change!/2
andfetch_field!/2
- [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
- [Ecto.Changeset] Add rollover logic for default incrementer in
optimistic_lock
- [Ecto.Query] Also expand macros when used inside
type/2
- [Ecto.Query] Ensure queries with non-cacheable queries in CTEs/combinations are also not-cacheable
v3.2 requires Elixir v1.6+.
- [Ecto.Query] Add common table expressions support
with_cte/3
andrecursive_ctes/2
- [Ecto.Query] Allow
dynamic/3
to be used inorder_by
,distinct
,group_by
, as well as inpartition_by
,order_by
, andframe
insidewindows
- [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 inEcto.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 toEcto.Type
that allows adapters to control embedding behaviour - [Ecto.Type] Add
use Ecto.Type
for convenience that implements the new required callbacks
- [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
- [Ecto.Changeset] Make sure
put_assoc
with empty changeset propagates on insert
- [Ecto.Repo] Add
:read_only
repositories - [Ecto.Schema] Also validate options given to
:through
associations
- [Ecto.Changeset] Do not mark
put_assoc
from[]
to[]
or fromnil
tonil
as change - [Ecto.Query] Remove named binding when excluding joins
- [mix ecto.gen.repo] Use
:config_path
instead of hardcoding toconfig/config.exs
- [Ecto.Repo] Allow
:default_dynamic_repo
option onuse Ecto.Repo
- [Ecto.Schema] Support
{:fragment, ...}
in the:where
option for associations
- [Ecto.Query] Fix handling of literals in combinators (union, except, intersection)
- [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
- [Ecto.Changeset] Expose the enum that was validated against in errors from enum-based validations
- [Ecto.Query] Add support for
type+over
- [Ecto.Schema] Allow schema fields to be excluded from queries
- [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
- [Ecto] Do not require Jason (i.e. it should continue to be an optional dependency)
- [Ecto.Repo] Make sure
many_to_many
andEcto.Multi
work with dynamic repos
v3.1 requires Elixir v1.5+.
- [Ecto.Changeset] Add
not_equal_to
option forvalidate_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
andEcto.Repo.get_dynamic_repo/0
(experimental) - [Ecto.Type] Cast naive_datetime/utc_datetime strings without seconds
- [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 oftype/2
and alias as second element oftype/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
- [Ecto.Query]
reverse_order
reverses by primary key if no order is given
- [Ecto.Query] Add
reverse_order/1
- [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
- [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 inhas_many/3
docs for more information
- [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
- [Decimal] Bump decimal dependency
- [Ecto.Repo] Remove unused
:pool_timeout
- [Ecto.Changeset] Add
count: :bytes
option invalidate_length/3
- [Ecto.Query] Support passing
Ecto.Query
inEcto.Repo.insert_all
- [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
- [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
toDateTime
when sending it to adapters
- [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
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
andecto.drop
commands - [Ecto.Adapters.PostgreSQL] Add ability to specify maintenance database name for PostgreSQL adapter for
ecto.create
andecto.drop
commands - [Ecto.Changeset] Store constraint name in error metadata for constraints
- [Ecto.Changeset] Add
validations/1
andconstraints/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
, anddelete/4
- [Ecto.Query] Support tuples in
where
andhaving
, allowing queries such aswhere: {p.foo, p.bar} > {^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 asselect: coalesce(p.title, p.old_title)
- [Ecto.Query] Support
filter/2
in queries, such asselect: filter(count(p.id), p.public == true)
- [Ecto.Query] The
:prefix
and:hints
options are now supported on bothfrom
andjoin
expressions - [Ecto.Query] Support
:asc_nulls_last
,:asc_nulls_first
,:desc_nulls_last
, and:desc_nulls_first
inorder_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
andexcept_all
- [Ecto.Query] Add support for
windows
andover
- [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 toupdate_all
anddelete_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
toRepo.insert/update/delete
that convertsEcto.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 tohas_many
/has_one
/belongs_to
/many_to_many
- [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
Ecto.Query.API.map/2
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 asinserted_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]
Ecto.Multi.run/3
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 expectson: expr
as last argument instead of simplyexpr
. This was done in order to properly support the:as
,:hints
and:prefix
options - [Ecto.Repo] The
:returning
option forupdate_all
anddelete_all
has been deprecated as those statements now supportselect
clauses - [Ecto.Repo] Passing
:adapter
via config is deprecated in favor of passing it onuse Ecto.Repo
- [Ecto.Repo] The
:loggers
configuration is deprecated in favor of "Telemetry Events"
- [Ecto.DateTime]
Ecto.Date
,Ecto.Time
andEcto.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]
Ecto.Multi.run/5
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 wrapsfragment
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 toon_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 inDBConnection.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 thefrom
/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 theprefix
key. - [Mix.Ecto]
Mix.Ecto.ensure_started/2
has been removed. However, in Ecto 2.2 theMix.Ecto
module was not considered part of the public API and should not have been used but we are listing this for guidance.
- [Ecto.Adapter] Split
Ecto.Adapter
intoEcto.Adapter.Queryable
andEcto.Adapter.Schema
to provide more granular repository APIs - [Ecto.Adapter] The
:sources
field inquery_meta
now contains three elements tuples with{source, schema, prefix}
in order to supportfrom
/join
prefixes (#2572) - [Ecto.Adapter] The database types
time
,utc_datetime
andnaive_datetime
should translate to types with seconds precision while the database typestime_usec
,utc_datetime_usec
andnaive_datetime_usec
should have microseconds precision (#2291) - [Ecto.Adapter] The
on_conflict
argument forinsert
andinsert_all
no longer receives a{:replace_all, list(), atom()}
tuple. Instead, it receives a{fields :: [atom()], list(), atom()}
wherefields
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 bothsource
andprefix
in it (#2490) - [Ecto.Adapter.Migration] A new
lock_for_migration/4
callback has been added. It is implemented by default byEcto.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 leveragingEcto.Adapters.SQL
do not have to perform any change) - [Ecto.Query] The
from
field inEcto.Query
now returns aEcto.Query.FromExpr
with the:source
field, unifying the behaviour infrom
andjoin
expressions (#2497) - [Ecto.Query] Tuple expressions are now supported in queries. For example,
where: {p.foo, p.bar} > {p.bar, p.baz}
should translate toWHERE (p.foo, p.bar) > (p.bar, 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 inselect: filter(count(p.id), p.public == true)
(#2487)
- See the CHANGELOG.md in the v2.2 branch