Not creating v7 uuids for ids

I'm using Ash 3.5 with AshPostgres. I have a Country resource with the following id attribute:
attributes do
uuid_v7_primary_key :id
attributes do
uuid_v7_primary_key :id
1. Create the table using Ash-generated migration 1a. Here's the generated extensions.json snapshot:
{
"ash_functions_version": 5,
"installed": [
"ash-functions",
"citext",
"uuid-ossp", // Unrelated question.. how did this get here?
"ash-uuid_v2"
]
}
{
"ash_functions_version": 5,
"installed": [
"ash-functions",
"citext",
"uuid-ossp", // Unrelated question.. how did this get here?
"ash-uuid_v2"
]
}
2. Populate the countries table via mix run priv/repo/seeds.exs See https://gist.github.com/dev-guy/7d8617b5da2d4207accf3365e88eb7fc for the seeder module. 3. Select * from countries 4. Notice that all of the id column values look like: 0f5f52a7-0ef0-445c-a59c-aacbcc56198a These are not v7 uuids. The number after the second hyphen is a 4, so they are v4 uuids. Have I not configured something correctly? Is this only a problem for seed data? 4a. Here is a uuid tester for reference:
case uuid do
<<_::binary-size(14), ?4, _rest::binary>> -> :v4
<<_::binary-size(14), ?7, _rest::binary>> -> :v7
_ -> :other_or_invalid
end
case uuid do
<<_::binary-size(14), ?4, _rest::binary>> -> :v4
<<_::binary-size(14), ?7, _rest::binary>> -> :v7
_ -> :other_or_invalid
end
Solution:
```elixir change fn changeset, _context -> if is_nil(Ash.Changeset.get_attribute(changeset, :id)) do Ash.Changeset.force_change_attribute(changeset, :id, Ash.UUID.generate()) # <- this is in your code you sent else...
Jump to solution
20 Replies
ZachDaniel
ZachDaniel•5mo ago
What is ash-uuid_v2? What do your seeds look like? I see it. Umm...pretty weird? I know it makes valid v7 uuids What does Ash.Resource.Info.attribute(Resource, :id) show? Can you share the whole resource?
Terris
TerrisOP•5mo ago
If you don't know what ash-uuid_v2 is, I'll remove it.
ZachDaniel
ZachDaniel•5mo ago
Well, hold on šŸ˜‚ Just show me the resource first if you can
Terris
TerrisOP•5mo ago
I am using a base resource so it's not as simple as it sounds. https://gist.github.com/dev-guy/60c2355508fed8450e4b78fa61ff6690 https://gist.github.com/dev-guy/94d2767876d06fbe156f0dc5d987a190 Also, I don't know how ash-uuid_v2 got there. And I don't know how to remove it. Grepping my codebase doesn't show it except in the snapshot. BTW I'm also using ash-oban. OK, what I couldn't find is in repo.ex. I was following some (probably old) documentation and added uuid-ossp and AshUUID.PostgresExtension in my sleep. I'll remove those and see what happens.
@impl true
def installed_extensions do
# Add extensions here, and the migration generator will install them.
["ash-functions", "citext", "uuid-ossp", AshUUID.PostgresExtension]
end
@impl true
def installed_extensions do
# Add extensions here, and the migration generator will install them.
["ash-functions", "citext", "uuid-ossp", AshUUID.PostgresExtension]
end
It's still creating v7 uuids (at least when creating seed data) with the following repo/extensions snapshot
{
"ash_functions_version": 5,
"installed": [
"ash-functions",
"citext"
]
}
{
"ash_functions_version": 5,
"installed": [
"ash-functions",
"citext"
]
}
mix run priv/repo/seeds.exs outputs :
INSERT INTO "countries" ("id","name","flag","updated_at","created_at","iso_3166","slug") VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING "flag","iso_3166","updated_at","created_at","slug","name","id" ["bd9338d5-cfa5-4dbf-96f6-e1409cddf0a4", "Zambia", ":flag_zm:", ~U[2025-05-26 16:40:49.535660Z], ~U[2025-05-26 16:40:49.535660Z], "ZM", "zambia"]
INSERT INTO "countries" ("id","name","flag","updated_at","created_at","iso_3166","slug") VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING "flag","iso_3166","updated_at","created_at","slug","name","id" ["bd9338d5-cfa5-4dbf-96f6-e1409cddf0a4", "Zambia", ":flag_zm:", ~U[2025-05-26 16:40:49.535660Z], ~U[2025-05-26 16:40:49.535660Z], "ZM", "zambia"]
Terris
TerrisOP•5mo ago
Here is the Country resource. :id looks correct, but creating an instance using a changeset creates a v4 uuid.
Terris
TerrisOP•5mo ago
iex(3)> Ash.UUIDv7.generate
"01970d84-dba7-7e23-b205-06b6e2bacfcc"
iex(3)> Ash.UUIDv7.generate
"01970d84-dba7-7e23-b205-06b6e2bacfcc"
Ash.UUIDv7.generate works correctly. Apparently Ash is not actually calling it.
ZachDaniel
ZachDaniel•5mo ago
WHat does your database show for the underlying type? Did you change from uuuid to uuidv7 and forget to run mix ash.codegen?
Terris
TerrisOP•5mo ago
I've been running mix ash.codegen many times due to regenerating the repo/extensions snapshot . I also delete all of the migrations before that.
CREATE TABLE countries (
id uuid DEFAULT uuid_generate_v7() PRIMARY KEY,
CREATE TABLE countries (
id uuid DEFAULT uuid_generate_v7() PRIMARY KEY,
ZachDaniel
ZachDaniel•5mo ago
šŸ¤” šŸ¤” šŸ¤” I don't understand how you could possibly be getting a regular uuid šŸ˜†
create :create do
accept [:name, :iso_3166, :flag]
change HealthCompassDirectory.Resources.Changes.GenerateSlug

change fn changeset, _context ->
if is_nil(Ash.Changeset.get_attribute(changeset, :id)) do
Ash.Changeset.force_change_attribute(changeset, :id, Ash.UUID.generate())
else
changeset
end
end
end
create :create do
accept [:name, :iso_3166, :flag]
change HealthCompassDirectory.Resources.Changes.GenerateSlug

change fn changeset, _context ->
if is_nil(Ash.Changeset.get_attribute(changeset, :id)) do
Ash.Changeset.force_change_attribute(changeset, :id, Ash.UUID.generate())
else
changeset
end
end
end
you're doing it šŸ™‚
Terris
TerrisOP•5mo ago
The issue has to do with creating instances of Country resource. The id attribute is configured to call Ash.UUIDv7.generate, but creating a resource via a changeset is calling Ash.UUID.generate
ZachDaniel
ZachDaniel•5mo ago
šŸ¤” On the create action you are calling you're setting the id to a uuid v4
Solution
ZachDaniel
ZachDaniel•5mo ago
change fn changeset, _context ->
if is_nil(Ash.Changeset.get_attribute(changeset, :id)) do
Ash.Changeset.force_change_attribute(changeset, :id, Ash.UUID.generate()) # <- this is in your code you sent
else
changeset
end
end
change fn changeset, _context ->
if is_nil(Ash.Changeset.get_attribute(changeset, :id)) do
Ash.Changeset.force_change_attribute(changeset, :id, Ash.UUID.generate()) # <- this is in your code you sent
else
changeset
end
end
Terris
TerrisOP•5mo ago
Yeah, I removed that.
ZachDaniel
ZachDaniel•5mo ago
and you recompiled and tried again? it won't fix the existing uuids in your database
Terris
TerrisOP•5mo ago
Right, I blow it away and start over. I will mix clean again.
ZachDaniel
ZachDaniel•5mo ago
I'm like...99% positive that its something in your code somehow setting these values to uuid v4s
Terris
TerrisOP•5mo ago
Sorry for wasting your time.
ZachDaniel
ZachDaniel•5mo ago
no need to apologize I'm not upset šŸ˜„
Terris
TerrisOP•5mo ago
I'm pretty sure if I hadn't fallen down this rabbit hole I would not have found out that user uuids were also v4, minor issue. Yep, rebuilding fixed it. Footgun.
Terris
TerrisOP•5mo ago
Oh, it was also useful to ask to get rid of the unnecessary extensions I added to the repo.

Did you find this page helpful?