Demo, all content is generated
Question

Postgres enum or text with a check constraint for order status?

Open · 301 views · asked by ayo_writes_code · edited

Order status: pending, paid, shipped, cancelled. Cursor made a Postgres enum, v0's generated types expect a string union. Which is easier to live with when I add 'refunded' later?

What I’ve tried

Read that you can't remove values from an enum. Tried adding a value in a migration and it worked, but I'm worried about the removing part.

Comment

3 answers

postgres_pete · edited

For a list that will change, text + check constraint. Changing the list is one migration that drops and re-adds the constraint. With an enum, adding is easy (alter type ... add value) but removing or renaming a value is painful.

alter table orders add constraint orders_status_check
  check (status in ('pending','paid','shipped','cancelled','refunded'));

supabase gen types turns enums into a nice union type, while a check becomes plain string. That's the one thing you give up.

Comment
Going with the check constraint, I can live with string types ayo_writes_code · edited
wes_codes · edited

I'd keep the enum, for the typed output alone. Removing a status in practice almost never happens, you stop using it. Renaming is alter type ... rename value since PG 10, that's fine.

Comment
Fair, rename is fine. It's the "we don't do shipped anymore, merge it into fulfilled" cases that hurt. Both are defensible. postgres_pete · edited
ingrid_h · edited

Third option: a small order_statuses lookup table with a foreign key. Overkill for 5 values, useful once statuses get labels, colors and sort order.

Comment