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개의 좋아요

무엇을 말씀하시는지 정확히 이해하지 못하겠습니다. "small action post"가 무엇인지도 잘 모르겠는데, 만약 토픽 분할에 대한 게시글이라면 그게 문제일 수 있겠네요. 현재 다음과 같은 오류가 발생하고 있습니다:

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번이고, "2021년 12월 11일에 이 토픽을 분할했습니다"라고 표시되어 있습니다. 바로 위 게시글은 2143번이므로, 2150번 게시글이 다른 토픽으로 이동되었고, 어떤 테이블에서 이를 참조하는 값이 잘못되었을 것 같다고 추측합니다.

1개의 좋아요

Unable to move posts between topics - #2 by nat 이 오류에 대한 수정 사항이 발표되었습니다.

3개의 좋아요

이 주제는 마지막 답변 후 90일이 지나면 자동으로 닫힙니다. 새로운 답변은 더 이상 허용되지 않습니다.