Команда rake posts:reorder_posts выдает ошибку UniqueViolation

Контекст: Я пытаюсь разделить пост. Для этого, как я полагаю, необходимо:

  • Создать новый пост в теме.
  • Отредактировать содержимое обоих постов так, как мне нужно.
  • Изменить владельца созданного поста, чтобы он совпадал с оригинальным.
  • Изменить временную метку созданного поста, чтобы она совпадала с оригинальной (возможно, добавив несколько секунд).
  • Выполнить posts:reorder_posts[topic_id], чтобы переместить мой ответ на нужное место в теме.

Первое, что я попробовал, — это вызов posts:reorder_post, «просто чтобы посмотреть», но он не удался:

root@discourse1-app:/var/www/discourse# rake "posts:reorder_posts[879]"
rake aborted!
PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "post_timings_unique"
DETAIL:  Key (topic_id, post_number, user_id)=(879, 93, 1) already exists.
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:110:in `exec'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:110:in `async_exec'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/postgres/connection.rb:209:in `run'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/active_record_postgres/connection.rb:38:in `block in run'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/active_record_postgres/connection.rb:34:in `block in with_lock'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/active_record_postgres/connection.rb:34:in `with_lock'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/active_record_postgres/connection.rb:38:in `run'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/postgres/connection.rb:181:in `exec'
/var/www/discourse/lib/tasks/posts.rake:383:in `block (3 levels) in <main>'
/var/www/discourse/lib/tasks/posts.rake:366:in `each'
/var/www/discourse/lib/tasks/posts.rake:366:in `block (2 levels) in <main>'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.4.1/lib/active_record/connection_adapters/abstract/transaction.rb:319:in `block in within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.4.1/lib/active_record/connection_adapters/abstract/transaction.rb:317:in `within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.4.1/lib/active_record/connection_adapters/abstract/database_statements.rb:316:in `transaction'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.4.1/lib/active_record/transactions.rb:209:in `transaction'
/var/www/discourse/lib/tasks/posts.rake:329:in `block in <main>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => posts:reorder_posts
(See full trace by running task with --trace)

Интересно, что я не вижу ни одного поста с номером 93 в теме. Я вижу 92 и 94. Пользователь 1 — это я, но посты 92 и 94 написаны не мной.

Ранее я уже разделил тему, возможно, пост 93 переместился в другую тему, я не знаю.

1 лайк

Столкнулся с той же проблемой, тот же трассировочный лог. Есть ли решение?

Думаю, это невозможно. Номер поста (post_number) пересчитывается, если пост был вынесен из темы (так как это не post_id, а порядок постов в теме). Возможно, это небольшой служебный пост, который не выглядит как «настоящий», но всё же учитывается как один (шёпоты тоже учитываются, но если вы планируете запускать rake-задачи, то, скорее всего, вы администратор и можете их видеть).

Интересно, помогло бы в данной ситуации удаление этого небольшого служебного поста? Звучит ли это как возможная проблема для вас, @UndecidedAdmin?

2 лайка

Не совсем понимаю, что вы имеете в виду. Не уверен, что такое «пост с небольшим действием», хотя если речь о посте о разделении тем, то да, это может быть проблемой. Я получаю эту ошибку:

PG::UniqueViolation: ERROR: duplicate key value violates unique constraint “post_timings_unique” (PG::UniqueViolation)
DETAIL: Key (topic_id, post_number, user_id)=(54, 2150, 1) already exists.

Когда я перехожу по этому URL:

https://[site]/t/[slug]/54/2150

Пост на самом деле имеет номер 2151, и в нём написано «Разделить эту тему 11 декабря 2021 года». Пост сразу выше — 2143, поэтому я предполагаю, что пост 2150 был перемещён в другую тему, и какая-то таблица содержит неправильную ссылку на него.

1 лайк

На Unable to move posts between topics - #2 by nat было объявлено об исправлении этой ошибки.

3 лайка

Эта тема была автоматически закрыта через 90 дней после последнего ответа. Новые ответы больше не принимаются.