PG::UndefinedTable: 오류: 관계 "voice_rooms"이(가) 존재하지 않습니다

Fatal: could not read Username for 'https://github.com'에서의 토론을 이어서:

GitHub 관련 문제는 이제 해결된 것으로 보이지만, 업그레이드가 실패합니다. 첫 번째 오류는 다음과 같습니다:

rake aborted!
StandardError: An error has occurred, this and all later migrations canceled: (StandardError) 
PG::UndefinedTable: ERROR:  relation "voice_rooms" does not exist

2-container 환경입니다(data도 실행했으며, 오류는 없었습니다). 그리고 최신 버전을 사용하고 있습니다.

해결책이 있을까요?

PG::UndefinedTable: ERROR: relation "voice_rooms" does not exist는 새로운 코어 번들에 포함된 voice 플러그인의 마이그레이션이 아직 실행되지 않았기 때문에 나타납니다.

rake aborted! 위에 어떤 내용이 있었나요?

글쎄… 꽤 많긴 해 :laughing: 하지만 내 관심을 끌 만한 건 없어.

x86_64 아키텍처 감지됨.                                                                                                                                                 
런처가 최신인지 확인 중                                                                                                                                       
런처가 최신 상태입니다                                                                                                                                                
기존 컨테이너 중지 중                                                                                                                                                
+ /usr/bin/docker stop -t 600 web_only                                                                                                                                
web_only                                                                                                                                                              
2.0.20260812-0036: discourse/base에서 가져오는 중                                                                                                                        
Digest: sha256:837e8ed4b5916baa36856b842ad84fe262b6b1b5550701f8844b13cc7acad7a5                                                                                       
Status: discourse/base:2.0.20260812-0036 이미지가 최신 상태입니다                                                                                                      
docker.io/discourse/base:2.0.20260812-0036                                                                                                                            
/usr/local/lib/ruby/gems/3.4.0/gems/pups-1.4.0/lib/pups.rb                                                                                                            
/usr/local/bin/pups --stdin                                                                                                                                           
I, [2026-09-03T08:55:23.418621 #1]  INFO -- : stdin에서 읽는 중                                                                                                      
I, [2026-09-03T08:55:23.453117 #1]  INFO -- : > thpoff echo "thpoff is installed!"                                                                                    
thpoff is installed!                                                                                                                                                  
I, [2026-09-03T08:55:23.461963 #1]  INFO -- : > /usr/local/bin/ruby -e 'if (ENV["DISCOURSE_SMTP_ADDRESS"] == "smtp.example.com" && ENV["DISCOURSE_SKIP_EMAIL_SETUP"] != "1"); puts "Aborting! Mail is not configured!"; exit 1; end'                                                                                                        
I, [2026-09-03T08:55:23.608522 #1]  INFO -- : > /usr/local/bin/ruby -e 'if ENV["DISCOURSE_HOSTNAME"] == "discourse.example.com"; puts "Aborting! Domain is not configured!"; exit 1; end'                                                                                                                                                   
I, [2026-09-03T08:55:23.743204 #1]  INFO -- : > /usr/local/bin/ruby -e 'if (ENV["DISCOURSE_CDN_URL"] || "")[0..1] == "//"; puts "Aborting! CDN must have a protocol specified"'                                                                                                        

이전 resenha 플러그인의 마이그레이션 버전이 새로운 voice 플러그인의 버전과 일치하는 것과 관련이 있을 것 같습니다. 아마도 먼저 설치했기 때문일 것입니다. 확실하지 않다면 psql에서 다음을 실행해 볼 수 있습니까?

  SELECT version, name, direction, created_at, git_version
  FROM schema_migration_details
  WHERE version = '20241107000000'
  ORDER BY created_at;

resenha/db/migrate/20241107000000_create_resenha_rooms.rb at b87ca4e20d649ba6b7bdc4615b289c414854889e · xfalcox/resenha · GitHubdiscourse/plugins/voice/db/migrate/20241107000000_create_voice_rooms.rb at main · discourse/discourse · GitHub 를 확인해 보세요.

이 충돌하는 마이그레이션 버전에 대한 코어 수정이 있어야 합니다. 다른 사용자들에게도 영향을 미칠 것으로 생각됩니다. 지켜봐 주세요.

네, 초기 단계에서 시도해 보았지만 나중에 제거했습니다.

수정:

pqsl이 그걸 답변했습니다

ERROR: relation “schema_migration_details” does not exist
LINE 2: FROM schema_migration_details

아, \c discourse도 필요합니다 :man_facepalming:

    version     |        name        | direction |        created_at         |               git_version                
----------------+--------------------+-----------+---------------------------+------------------------------------------
 20241107000000 | CreateResenhaRooms | up        | 2026-03-03 17:21:17.12944 | 8ffdde5e59cb655d7f6c67cd316395807ce01df9

음 - 아마도 실행된 것으로 가정되었지만 실제로는 실행되지 않은 resenha 마이그레이션인 것 같습니다. 코어에서 음성(voice)에 동일한 마이그레이션 버전 번호가 사용되므로, 갑자기 voice_rooms에 컬럼을 추가하려고 하면 테이블 이름이 여전히 resenha_rooms이기 때문에 작동하지 않습니다.

일단 psql에서 다음을 실행해 보세요:

DO
$$
  DECLARE
    has_resenha boolean;
    has_voice   boolean;
    table_pair  record;
  BEGIN
    SELECT EXISTS (SELECT 1
                   FROM unnest(ARRAY [
                     'resenha_rooms',
                     'resenha_room_memberships',
                     'resenha_sessions',
                     'resenha_co_presences',
                     'resenha_recordings',
                     'resenha_invites'
                     ]) AS names(name)
                   WHERE to_regclass(format('public.%I', name)) IS NOT NULL)
    INTO has_resenha;

    SELECT EXISTS (SELECT 1
                   FROM unnest(ARRAY [
                     'voice_rooms',
                     'voice_room_memberships',
                     'voice_sessions',
                     'voice_co_presences',
                     'voice_recordings',
                     'voice_invites'
                     ]) AS names(name)
                   WHERE to_regclass(format('public.%I', name)) IS NOT NULL)
    INTO has_voice;

    IF has_resenha AND has_voice THEN
      RAISE EXCEPTION
        'Both Resenha and Voice tables exist. Nothing was changed.';
    END IF;

    IF NOT has_resenha THEN
      IF to_regclass('public.voice_rooms') IS NOT NULL THEN
        RAISE NOTICE 'The tables have already been renamed.';
        RETURN;
      END IF;

      RAISE EXCEPTION
        'Neither resenha_rooms nor voice_rooms exists. Nothing was changed.';
    END IF;

    IF EXISTS (SELECT 1
               FROM schema_migrations
               WHERE version = '20260831162602') THEN
      RAISE EXCEPTION
        'The rename migration is already recorded. Nothing was changed.';
    END IF;

    FOR table_pair IN
      SELECT *
      FROM (VALUES ('resenha_rooms', 'voice_rooms', '20241107000000'),
                   ('resenha_room_memberships', 'voice_room_memberships',
                    '20241107000000'),
                   ('resenha_sessions', 'voice_sessions', '20260305165400'),
                   ('resenha_co_presences', 'voice_co_presences',
                    '20260305165401'),
                   ('resenha_recordings', 'voice_recordings', '20260717172530'),
                   ('resenha_invites', 'voice_invites',
                    '20260813160047')) AS pairs(old_name, new_name, migration_version)
      LOOP
        IF EXISTS (SELECT 1
                   FROM schema_migrations
                   WHERE version = table_pair.migration_version) AND
           to_regclass(format('public.%I', table_pair.old_name)) IS NULL THEN
          RAISE EXCEPTION
            'Migration % is recorded, but table % is missing. Nothing was changed.',
            table_pair.migration_version,
            table_pair.old_name;
        END IF;

        IF to_regclass(format('public.%I', table_pair.old_name)) IS NOT NULL THEN
          EXECUTE format(
            'ALTER TABLE public.%I RENAME TO %I',
            table_pair.old_name,
            table_pair.new_name
                  );

          RAISE NOTICE 'Renamed % to %', table_pair.old_name, table_pair.new_name;
        END IF;
      END LOOP;
  END
$$;

다음과 같은 작업을 수행합니다:

  1. 존재하는 Resenha 및 Voice 테이블을 확인합니다.
  2. 두 테이블이 모두 존재하는 경우 계속 진행하는 것을 거부합니다(이러한 상황은 예상하지 않습니다).
  3. 기록된 마이그레이션이 우리가 기대하는 것과 일치하는지 확인합니다.
  4. 기존 테이블 이름을 변경합니다:
    • resenha_rooms → voice_rooms
    • resenha_room_memberships → voice_room_memberships
    • resenha_sessions → voice_sessions
    • resenha_co_presences → voice_co_presences
    • resenha_recordings → voice_recordings
    • resenha_invites → voice_invites
  5. 이는 현재 겪고 있는 이상한 중간 상태를 해결하는 데 도움이 됩니다. 이후 재빌드(rebuild)가 성공해야 합니다.

이것은 나머지 코어 마이그레이션이 성공할 수 있도록 허용합니다(이름 변경을 수행하는 가장 최근의 코어 음성 마이그레이션은 아무것도 하지 않는 no-op이 됩니다).

우리 팀과 이 내용을 rake task로 커밋해야 하는지 확인해 보겠습니다.

감사합니다! 완벽하게 작동했습니다.