How to add a unique index on an existing table column? #1782
-
Hey 👋 I previously added this migration:
However, I recently discovered a bug: the key column should have been marked as .unique(), but it isn’t. Is there a clean way to migrate this table now to enforce uniqueness on the key column and have it properly reflected in the schema? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Hello @pedrommcarrasco,
Please follow precisely the instructions at How to Recreate a Database Table. You have to be careful because the badges table may contain duplicate entries for a given key, due to the lack of unique index. You MUST come up with a strategy for disambiguating those entries, here, so that you have the guarantee that the fix runs correctly on all user devices. In the following sample code, I'll prefer the most "recent" row, by picking the row with the maximum migrator.registerMigration("Add unique index on badges.key") { db in
try db.create(table: "new_badges") { t in
t.primaryKey("id", .text).notNull() // <- already unique
t.column("tier", .text).notNull()
t.column("name", .text).notNull()
t.column("key", .text).notNull().unique() // <- add the missing index
t.column("hint", .text).notNull()
t.column("imageUrl", .text).notNull()
}
try db.execute(sql: """
INSERT OR IGNORE -- ignore duplicates on the 'key' column
INTO new_badges
SELECT * FROM badges
ORDER BY rowid DESC -- tie breaker
""")
try db.drop(table: "badges")
try db.rename(table: "new_badges", to: "badges")
} Note: I did not add |
Beta Was this translation helpful? Give feedback.
Hello @pedrommcarrasco,
Please follow precisely the instructions at How to Recreate a Database Table.
You have to be careful because the badges table may contain duplicate entries for a given key, due to the lack of unique index. You MUST come up with a strategy for disambiguating those entries, here, so that you have the guarantee that the fix runs correctly on all user devices.
In the following sample code, I'll prefer the most "recent" row, by picking the row with the maximum
rowid
(a value that all SQLite tables have, and is usually growing). You will …