Вопрос или проблема
Я использую сервер на Node.js и PostgreSQL через Docker с использованием Docker Compose.
Когда я пытаюсь добавить ограничение @unique
к существующей таблице и запускаю prisma migrate dev
, это работает не так, как ожидается.
Вот пример:
model User {
id Int @id @default(autoincrement())
username String
}
Это моя начальная таблица User. Затем я добавил
email String? @unique
.
Когда я снова запускаю docker-compose up, что запускает prisma migrate dev
, я получаю следующее сообщение:
Будет добавлено уникальное ограничение для столбца [email] в таблице User. Если существуют дублирующиеся значения, это приведет к ошибке.
На этом этапе сервер зависает и не продолжает работу. У меня нет никаких дублирующихся значений. Для пояснения, у меня есть три соответствующих файла.
docker-compose.yml
services:
backend-dev:
platform: linux/amd64
build:
context: .
dockerfile: Dockerfile.dev
image: backend-dev
stdin_open: true # Позволяет интерактивный режим
tty: true # Включает поддержку терминала
ports:
- '4000:4000'
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
env_file:
- .env
environment:
DATABASE_URL: ${DATABASE_URL}
depends_on:
- postgres-db
postgres-db:
platform: linux/amd64
image: postgres:16.3
ports:
- '5432:5432'
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
....
volumes:
postgres_data:
Dockerfile.dev
FROM --platform=linux/amd64 node:20-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY prisma ./prisma/
COPY . .
RUN npx prisma generate
RUN chmod +x ./entrypoint-dev.sh
EXPOSE 4000
ENTRYPOINT ["sh", "./entrypoint-dev.sh"]
CMD [ "npm", "run", "dev" ]
entrypoint-dev.sh
#!/bin/sh
npx prisma migrate dev --name added_email
exec "$@"
Почему я не могу добавить ограничение @unique? Я тестировал это с Supabase, и это сработало, но когда я использую свою локальную PostgreSQL в Docker, это не удается.
Ответ или решение
Для решения проблемы с добавлением ограничения @unique
в существующую таблицу с помощью команды prisma migrate dev
в Docker, давайте рассмотрим последовательность шагов и потенциальные причины ошибки.
Проблема
Вы указали, что пытаетесь добавить email String? @unique
к модели User
. При попытке выполнить миграцию, Prisma сообщает, что не может добавить уникальное ограничение, если в таблице уже существуют дублирующиеся значения. Система зависает, потому что операция может ожидать подтверждения или блокируется в ожидании ресурса.
Возможные причины
-
Существующие Дублирующиеся Значения:
Хотя вы упомянули, что не имеете дублирующихся значений, следует убедиться, что в колонкеemail
в вашей базе данных (все записи) действительно нет дубликатов. Попробуйте выполнить SQL-запрос для проверки уникальности:SELECT email, COUNT(*) FROM "User" GROUP BY email HAVING COUNT(*) > 1;
Если запрос вернет строки, это означает, что у вас есть дубликаты, и вам необходимо решить эту проблему.
-
Несогласованность Состояния Базы Данных:
Возможно, порядок миграций нарушен, или предыдущие миграции не были успешно применены. Убедитесь, что ваша база данных и структура Prisma на одинаковой стадии. -
Заключение В Блокировке:
Ваша командаdocker-compose up
может зависать, если ресурсы базы данных заблокированы другой транзакцией. Это может происходить, если другая операция записывает данные в базу данных.
Решение
-
Проверка Дубликатов:
Прежде всего, выполните проверку на дубликаты, как указано выше. Убедитесь, что у вас нет конфликтующих значений в колонкеemail
. -
Применение Миграции поэтапно:
Если вы хотите вручную применить миграции, рассмотрите возможность использованияprisma migrate reset
. Важно помнить: эта команда удалит все данные в базе:npx prisma migrate reset
Поскольку данный подход очищает базу данных, используйте его только если это допустимо для вашего проекта.
-
Изменение Скрипта Запуска:
В вашемentrypoint-dev.sh
сценарии, добавьте дополнительную проверку успеваемости миграций перед запуском приложения. Например:#!/bin/sh npx prisma migrate dev --name added_email --skip-generate # Убедитесь, что миграция выполнена успешно if [ $? -ne 0 ]; then echo "Migration failed, exiting." exit 1 fi exec "$@"
-
Проверка Логов Docker:
Просмотрите логи вашего контейнера PostgreSQL для более детальной информации о том, что происходит. Логи можно просмотреть с помощью команды:docker-compose logs postgres-db
Заключение
После выполнения вышеуказанных шагов вы должны быть в состоянии успешно применить миграцию с уникальным ограничением. Основная задача заключается в идентификации и устранении возможных конфликтов в данных, а также в управлении состоянием миграций в вашей базе данных.