Skip to content

fix: bulk_create with upsert now updates update_timestamp fields#697

Merged
zachdaniel merged 2 commits intoash-project:mainfrom
mbaertschi:fix/bulk_upsert_updated_at
Feb 20, 2026
Merged

fix: bulk_create with upsert now updates update_timestamp fields#697
zachdaniel merged 2 commits intoash-project:mainfrom
mbaertschi:fix/bulk_upsert_updated_at

Conversation

@mbaertschi
Copy link
Copy Markdown
Contributor

@mbaertschi mbaertschi commented Feb 20, 2026

Summary

  • update_timestamp attributes (e.g. updated_at) were never included in the
    ON CONFLICT DO UPDATE SET clause because they have writable?: false and
    thus never appear in changeset.attributes. This ensures fields with
    update_defaults are always included when an upsert modifies fields.

  • Adds a touch_update_defaults? data layer context option to opt out of this
    behavior when needed:

    Ash.bulk_create(inputs, Resource, :create,
      upsert?: true,
      upsert_fields: [:name],
      context: %{data_layer: %{touch_update_defaults?: false}}
    )
    

Closes #696

Contributor checklist

Leave anything that you believe does not apply unchecked.

  • I accept the AI Policy, or AI was not used in the creation of this PR.
  • Bug fixes include regression tests
  • Chores
  • Documentation changes
  • Features include unit/acceptance tests
  • Refactoring
  • Update dependencies

…onflict

update_timestamp attributes (e.g. updated_at) were never included in the
ON CONFLICT DO UPDATE SET clause because they have writable?: false and
thus never appear in changeset.attributes. This ensures fields with
update_defaults are always included when an upsert modifies fields.

Closes ash-project#696
Copy link
Copy Markdown
Contributor

@zachdaniel zachdaniel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also add this same logic to ash_sqlite. Would you mind opening a similar PR or just an issue to track that? 🙇

@mbaertschi
Copy link
Copy Markdown
Contributor Author

I'll have a look next week. If we implement this for ash_sqlite as well, should we consider to move touch_update_defaults? to the bulk_create_options ?

@zachdaniel zachdaniel merged commit afb3a5c into ash-project:main Feb 20, 2026
67 checks passed
@zachdaniel
Copy link
Copy Markdown
Contributor

Yeah, I think that would be a great idea 👍.

@zachdaniel
Copy link
Copy Markdown
Contributor

It can set that context automatically, and would work for ETS for example.

mbaertschi added a commit to mbaertschi/ash_sqlite that referenced this pull request Feb 25, 2026
Ports ash-project/ash_postgres#697 to ash_sqlite. update_timestamp
attributes (e.g. updated_at) were never included in the ON CONFLICT
DO UPDATE SET clause because they have writable?: false. Now fields
with update_defaults are always included when an upsert modifies
fields. Can be disabled via context:
%{data_layer: %{touch_update_defaults?: false}}
zachdaniel pushed a commit to ash-project/ash_sqlite that referenced this pull request Feb 25, 2026
Ports ash-project/ash_postgres#697 to ash_sqlite. update_timestamp
attributes (e.g. updated_at) were never included in the ON CONFLICT
DO UPDATE SET clause because they have writable?: false. Now fields
with update_defaults are always included when an upsert modifies
fields. Can be disabled via context:
%{data_layer: %{touch_update_defaults?: false}}
zachdaniel pushed a commit to ash-project/ash_sqlite that referenced this pull request Mar 2, 2026
…geset context (#208)

fix: bulk_create with upsert now updates update_timestamp fields

Ports ash-project/ash_postgres#697 to ash_sqlite. update_timestamp
attributes (e.g. updated_at) were never included in the ON CONFLICT
DO UPDATE SET clause because they have writable?: false. Now fields
with update_defaults are always included when an upsert modifies
fields. Can be disabled via context:
%{data_layer: %{touch_update_defaults?: false}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bulk_create with upsert? does not update update_timestamp fields on conflict

2 participants