Repository navigation
Description
Code of Conduct
- I agree to follow this project's Code of Conduct
AI Policy
- I agree to follow this project's AI Policy, or I agree that AI was not used while creating this issue.
Versions
Elixir 1.18.4 (compiled with Erlang/OTP 28)
Ash 3.5.28
ash_postgres 2.6.11
Operating system
macOS 13.6.3 (22G436)
Current Behavior
When creating a new resource and defining at least these blocks:
defmodule AshPostgresRollback.Domain.SecondResource do
use Ash.Resource,
otp_app: :ash_postgres_rollback,
domain: AshPostgresRollback.Domain,
data_layer: AshPostgres.DataLayer
postgres do
table "second_resources"
repo AshPostgresRollback.Repo
references do
reference :first_resource, deferrable: :initially
end
end
# skip
relationships do
belongs_to :first_resource, AshPostgresRollback.Domain.FirstResource
end
endash.codegen will bundle the creation of a table for the resource, as well as the creation of the foreign key & adjustment of the DEFERRABLE behaviour into the same migration. This work in the up direction just fine (it first creates the table, then the FK, then alters the constraint), but in the down direction, the generated migration first drops the constraint, then the table, then tries to alter the constraint on an already dropped table:
defmodule AshPostgresRollback.Repo.Migrations.SecondResource do
# skip
def down do
drop(constraint(:second_resources, "second_resources_first_resource_id_fkey"))
drop(table(:second_resources))
execute(
"ALTER TABLE second_resources ALTER CONSTRAINT second_resources_first_resource_id_fkey DEFERRABLE INITIALLY DEFERRED"
)
end
endReproduction
I prepared a sample GitHub repo that demonstrates the issue, available here. The linked migration shows that it first attempts to drop the table second_resources, then it tries to alter a constraint on an already dropped table, resulting in a failure.
(Please excuse the nonsensical resources in the sample repo, and the strange formatting of migrations 😬)
Expected Behavior
I think there’s probably a bunch of solutions here, not sure which one is the best one…
- The
ALTER CONSTRAINTstatement could be placed at the top of thedownblock, thus making thedownblock truly in a reverse order from theupblock - The changes could be split into two migrations, one to create the tables, one to alter the constraint settings, then correct rollback behaviour would be achieved automatically?
- (Sidenote?) Perhaps it should be noted that both
upanddownblocks (as shown in the sample repo) make the constraintDEFERRABLE INITIALLY DEFERRED, so the rollback behaviour wouldn’t even truly restore the previous/original setting (I believeINITIALLY DEFERREDis not the default value… I think)
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsSomeday
Activity
zachdaniel commentedon Jul 18, 2025
Thanks for the report! PRs welcome to help w/ proper ordering of these steps 🙇
WillG2001 commentedon Mar 16, 2026
I'm going to give this one a shot!
taunima commentedon Oct 29, 2026
Is this problem still open?
zachdaniel commentedon Oct 29, 2026
Looks like someone just opened a PR to fix at least one of these issues: #912
I'd confirm that the issue is resolved here when using that implementation. If so then we can close this issue 😄
taunima commentedon Nov 6, 2026
So I reproduced the same environment with the updated PR fix of #912 and this issue #595 is still not fixed. For a new table with reference(:post, deferrable: :initially), the generated down runs drop table(...) and then execute("ALTER TABLE example.posts ALTER CONSTRAINT posts_post_id_fkey DEFERRABLE INITIALLY DEFERRED") on the already-dropped table. I’d like to work on a fix for the ordering if that is ok?
zachdaniel commentedon Nov 6, 2026
Sounds great, thanks!