Итак, я попытался обновить свою доску сегодня утром и получил ошибку:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint “index_users_on_username”
В ошибке указан пользователь “MikeC”. Я немного покопался и получил совет восстановить postgres_data, снова запустить доску, а затем проверить базу данных на наличие дубликатов. Я выполнил быстрый запрос для username_lower = ‘mikec’ и нашёл одну строку. Затем я нашёл этот изящный запрос:
SELECT username_lower, count(*) from users GROUP by username_lower HAVING count(*) > 1;
Он вернул пустой результат. Так где же дубликат? Буду признателен за любую помощь. Я работаю со старыми данными, но хотел бы иметь возможность корректно пересобрать приложение.
Вот как я решил эту проблему, хотя уверен, что есть лучший способ:
Я зашел в админ-панель и поискал ‘MikeC’, что вернуло двух пользователей. Тогда я переименовал самого старого из них и, вместо повторного запуска rebuild, просто подключился к базе данных и выполнил реиндексацию:
cd /var/discourse
./launcher enter app
sudo -i postgres psql discourse
discourse# REINDEX SCHEMA CONCURRENTLY public;
Если бы нашлось ещё дубликат, я бы вернулся в веб-интерфейс, поискал этого пользователя, переименовал более старую запись и повторил процесс. Так, пока не найдено дубликатов. Затем запускаю rebuild, и всё работает!
Однако я хотел бы узнать:
Почему Discourse допускает дубликаты? Имя пользователя может быть регистронезависимым, но поле username_lower нормализуется к значению, которое должно быть уникальным. Это выглядит как довольно серьёзная ошибка.
Какой более эффективный способ найти и исправить эти дубликаты?
Я не думаю, что существует лучший способ. Дубликаты имен пользователей не допускаются, но, похоже, в предыдущей ошибке проверка на нижний регистр не работала. Недавно была ещё одна тема об этом.