Я работаю над проектом Django, используя контейнер PostgreSQL в Docker. Я добавил ManyToManyField в одну из своих моделей. Я храню миграции в .gitignore, поскольку мои локальные и рабочие базы данных различаются, поэтому я отправлял изменения модели только на GitHub. На своем сервере я извлек код и запустил docker Compose, который автоматически запускает makemigrations и миграцию. Ошибок и предупреждений не было, а созданный файл миграции правильно включает поле ManyToMany. Django показывает примененную миграцию. Однако, когда я пытаюсь получить доступ к отношению ManyToMany во время выполнения, я получаю сообщение об ошибке базы данных, сообщающее, что объединяющая таблица не существует.
Среда
- Django
- PostgreSQL
- Docker
Код: Выделить всё
class Contact(models.Model):
...
class CallCampaign(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
error = models.TextField(blank=True, null=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
selected_contacts = models.ManyToManyField('Contact', blank=True)
...
Файл миграции включает ManyToManyField:
Код: Выделить всё
migrations.CreateModel(
name='CallCampaign',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('error', models.TextField(blank=True, null=True))
('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='companies.company')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('selected_contacts', models.ManyToManyField(blank=True, to='contacts.contact')),
],
),
Что происходит во время выполнения
Код: Выделить всё
>>> from contacts.models import CallCampaign
>>> c = CallCampaign.objects.first()
>>> c.selected_contacts
>>> c.selected_contacts.all()
Код: Выделить всё
django.db.utils.ProgrammingError:
relation "contacts_callcampaign_selected_contacts" does not exist
LINE 1: ..."."created_at" FROM "contacts_contact" INNER JOIN "contacts_...
Существующие таблицы:
Код: Выделить всё
contacts_callcampaign
contacts_contact
contacts_callhistory
Код: Выделить всё
contacts_callcampaign_selected_contacts
В таблице django_migrations показано:
Код: Выделить всё
app | name | applied
--------|--------------|--------
contacts| 0001_initial | 2025-12-29 16:21:00
Код: Выделить всё
python manage.py makemigrations
# No changes detected
python manage.py migrate
# No migrations to apply
Настройка Docker (упрощенная)
Код: Выделить всё
services:
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data/
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
web:
build: .
command: >
sh -c "
python manage.py makemigrations --noinput &&
python manage.py migrate --noinput
"
depends_on:
db:
condition: service_healthy
volumes:
postgres_data:
Вопросы
- Как можно пометить миграцию Django как примененную, если таблица ManyToMany не была создана?
- Это ожидаемое поведение при миграции Django? (т. е. отсутствие гарантии атомарности для всей миграции)
- Как это можно предотвратить при использовании Docker с постоянными базами данных?
- Что мне делать сейчас?
Подробнее здесь: https://stackoverflow.com/questions/798 ... docker-pos
Мобильная версия