Prisma migrate dev на Docker с ошибкой уникального ограничения

Вопрос или проблема

Я использую сервер на 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 сообщает, что не может добавить уникальное ограничение, если в таблице уже существуют дублирующиеся значения. Система зависает, потому что операция может ожидать подтверждения или блокируется в ожидании ресурса.

Возможные причины

  1. Существующие Дублирующиеся Значения:
    Хотя вы упомянули, что не имеете дублирующихся значений, следует убедиться, что в колонке email в вашей базе данных (все записи) действительно нет дубликатов. Попробуйте выполнить SQL-запрос для проверки уникальности:

    SELECT email, COUNT(*)
    FROM "User"
    GROUP BY email
    HAVING COUNT(*) > 1;

    Если запрос вернет строки, это означает, что у вас есть дубликаты, и вам необходимо решить эту проблему.

  2. Несогласованность Состояния Базы Данных:
    Возможно, порядок миграций нарушен, или предыдущие миграции не были успешно применены. Убедитесь, что ваша база данных и структура Prisma на одинаковой стадии.

  3. Заключение В Блокировке:
    Ваша команда docker-compose up может зависать, если ресурсы базы данных заблокированы другой транзакцией. Это может происходить, если другая операция записывает данные в базу данных.

Решение

  1. Проверка Дубликатов:
    Прежде всего, выполните проверку на дубликаты, как указано выше. Убедитесь, что у вас нет конфликтующих значений в колонке email.

  2. Применение Миграции поэтапно:
    Если вы хотите вручную применить миграции, рассмотрите возможность использования prisma migrate reset. Важно помнить: эта команда удалит все данные в базе:

    npx prisma migrate reset

    Поскольку данный подход очищает базу данных, используйте его только если это допустимо для вашего проекта.

  3. Изменение Скрипта Запуска:
    В вашем 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 "$@"
  4. Проверка Логов Docker:
    Просмотрите логи вашего контейнера PostgreSQL для более детальной информации о том, что происходит. Логи можно просмотреть с помощью команды:

    docker-compose logs postgres-db

Заключение

После выполнения вышеуказанных шагов вы должны быть в состоянии успешно применить миграцию с уникальным ограничением. Основная задача заключается в идентификации и устранении возможных конфликтов в данных, а также в управлении состоянием миграций в вашей базе данных.

Оцените материал
Добавить комментарий

Капча загружается...