Хорошо — скорее всего, это миграция resenha, которая, как предполагалось, была выполнена, но на самом деле не выполнялась. Поскольку в core для голосовых функций используется тот же номер версии миграции, попытка добавить столбец для 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
$$;
Скрипт выполняет следующее:
- Проверяет, какие таблицы Resenha и Voice существуют.
- Откажется продолжать, если обе существуют (я не ожидаю, что это произойдёт).
- Проверяет, что записанные миграции соответствуют ожидаемым.
- Переименовывает существующие таблицы:
- 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
- Это поможет решить проблему с тем странным промежуточным состоянием, в котором вы находитесь. Пересборка после этого должна пройти успешно.
Это должно позволить остальным вашим миграциям core завершиться успешно (самая последняя миграция core для голосовых функций, которая выполняет переименование, будет пропущена как noop).
Я проверю с нашей командой, стоит ли нам закоммитить это как rake-задачу.