cannot alter table because it has pending trigger events

9 августа 2016 г. 6:18

Ошибка cannot alter table because it has pending trigger events (нельзя выполнить ALTER TABLE, так как с этим объектом связаны отложенные события триггеров) чаще всего означает, что одно или несколько свойств полей не могут быть изменены за одну транзакцию. Если дословно переводить, может быть непонятно. Да и моя расшифровка не блещет полнотой передачи понимания, поэтому просто покажу примеры.

Убрать blank=True с полей

Допустим имеем модель:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django.utils.encoding import python_2_unicode_compatible


@python_2_unicode_compatible
class MyModel(models.Model):
    title = models.CharField(max_length=100, null=True, blank=True)
    content = models.TextField(null=True, blank=True)
    template = models.CharField(max_length=255, null=True, blank=True)


    def __str__(self):
        return self.title

Так как null=True - избыточное свойство для полей CharField, TextField и т. д., поэтому его нужно убрать:

...
class MyModel(models.Model):
    title = models.CharField(max_length=100, blank=True)
    content = models.TextField(blank=True)
    template = models.CharField(max_length=255, blank=True)
...

Затем выполняем makemigrations. Заметьте, если сразу сделать migrate, то можем получить ошибку cannot alter table because it has pending trigger events. Чтобы этого не было, в созданной миграции пишем метод set_blank(apps, schema_editor) и добавляем migrations.RunPython(set_blank) в список operations для выполнения нашего метода:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


def set_blank(apps, schema_editor):
    fields = ('content', 'template', 'title')

    for obj in apps.get_model('my_app', 'MyModel').objects.all():
        old_field_values = {field: getattr(obj, field) for field in fields}

        for field in fields:
            setattr(obj, field, getattr(obj, field) or '')

        dirty = False
        for field, value in old_field_values.items():
            if value != getattr(obj, field):
                dirty = True
        if dirty:
            obj.save()


def set_blank_simple(apps, schema_editor):
    MyModel = apps.get_model('my_app', 'MyModel')
    for obj in MyModel.objects.all():
        obj.content = obj.content or ''
        obj.template = obj.template or ''
        obj.title = obj.title or ''
        obj.save()


class Migration(migrations.Migration):

    dependencies = [
        ('my_app', '0007_auto_20160509_1225'),
    ]

    operations = [
        # migrations.RunPython(set_blank_simple),  # Простая функция ''
        migrations.RunPython(set_blank),  # более оптимизированная функция ''
        migrations.AlterField(
            model_name='mymodel',
            name='content',
            field=models.TextField(default='', blank=True),
            preserve_default=False,
        ),
        migrations.AlterField(
            model_name='mymodel',
            name='template',
            field=models.CharField(default='', max_length=255, blank=True),
            preserve_default=False,
        ),
        migrations.AlterField(
            model_name='mymodel',
            name='title',
            field=models.CharField(default='', max_length=100, blank=True),
            preserve_default=False,
        ),
    ]

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

Также можно попробовать вручную или через management команду заполнить данные пустой строкой ('') - мне помогает.

Оцените статью

5 из 5 (всего 3 оценки)

captcha
Отмеченные звёздочкой поля ( * ) являются обязательными для заполнения.

Спасибо за ваш отзыв!

После нажатия кнопки "Отправить" ваше сообщение будет доставлено мне на почту.

Автор статьи

Артём Мальцев

Веб-разработчик, владеющий знаниями языка программирования Python, фреймворка Django, системы управления содержимым сайта Django CMS, платформы для создания интернет-магазина Django Shop и многих различных приложений, использующих эти технологии.

Права на использование материала, расположенного на этой странице https://vivazzi.pro/ru/it/cannot-alter-table-because-it-has-pending-trigger-events/:

Разрешается копировать материал с указанием её автора и ссылки на оригинал без использования параметра rel="nofollow" в теге <a>. Использование:

Автор статьи: Артём Мальцев
Ссылка на статью: <a href="https://vivazzi.pro/ru/it/cannot-alter-table-because-it-has-pending-trigger-events/">https://vivazzi.pro/ru/it/cannot-alter-table-because-it-has-pending-trigger-events/</a>

Больше: Правила использования сайта

Представляю вашему вниманию книгу, написанную моим близким другом Максимом Макуриным: Секреты эффективного управления ассортиментом.

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

Комментарии: 0

Вы можете оставить комментарий как незарегистрированный пользователь.

Но зарегистрировавшись, вы сможете:

  • получать оповещения об ответах
  • просматривать свои комментарии
  • иметь возможность использовать все функции разработанных сервисов

Для комментирования от своего имени войдите или зарегистрируйтесь на сайте Vuspace

Отправить

На данный момент нет специального поиска, поэтому я предлагаю воспользоваться обычной поисковой системой, например, Google, добавив "vivazzi" после своего запроса.

Попробуйте

Выберите валюту для отображения денежных единиц