Миграция AlterField работает для некоторых полей, а не для других, но все они имеют одинаковые изменения - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть миграция, которая меняет поле varchar на поле внешнего ключа. В базе данных нет значений для этих полей varchar - все значения равны нулю, так что это не является фактором в этой проблеме. Две из операций AlterField работали без каких-либо проблем, но две другие не удалось. Когда мы попытались запустить миграцию, мы получили ValueError, что связанная модель не может быть решена.

Вот что находится в models.py - код фактически находится в другой системе, и я набираю заново. Я также не могу ввести настоящие имена из-за проблем безопасности, поэтому я запутываю имена:

class A(DisplayValuePair):
    pass

class B(DisplayValuePair):
    pass

class C(DisplayValuePair):
    pass

class D(DisplayValuePair):
    pass

class PropertiesFile(models.Model):
    # there lots of other foreign key fields that already exist in the model
    # that are defined the same way, but these are new. The fields used to all
    # be models.CharField
    my_a_field = models.ForeignKey(A, null=True, blank=True, on_delete=_PROTECT)
    my_b_field = models.ForeignKey(B, null=True, blank=True, on_delete=_PROTECT)
    my_c_field = models.ForeignKey(C, null=True, blank=True, on_delete=_PROTECT)
    my_d_field = models.ForeignKey(D, null=True, blank=True, on_delete=_PROTECT)

Когда выполняется makemigrations, создается миграция

migrations.AlterField(
    model_name="propertiesfile",
    name="my_a_field",
    field=models.ForeignKey(blank=true, null=True, 
                            on_delete=django.db.models.delete.PROTECT,
                            to='data_exporter_app.A'),
),
migrations.AlterField(
    model_name="propertiesfile",
    name="my_b_field",
    field=models.ForeignKey(blank=true, null=True, 
                            on_delete=django.db.models.delete.PROTECT,
                            to='data_exporter_app.B'),
),
migrations.AlterField(
    model_name="propertiesfile",
    name="my_c_field",
    field=models.ForeignKey(blank=true, null=True, 
                            on_delete=django.db.models.delete.PROTECT,
                            to='data_exporter_app.C'),
),
migrations.AlterField(
    model_name="propertiesfile",
    name="my_d_field",
    field=models.ForeignKey(blank=true, null=True, 
                            on_delete=django.db.models.delete.PROTECT,
                            to='data_exporter_app.D'),
),

Когда я запускаю миграцию на одном конкретном сервере, происходит сбой при изменении my_c_field. Первые два, my_a_field и my_b_field, конвертируются в поля внешнего ключа в таблице без каких-либо проблем. Но my_c_field и my_d_field терпят неудачу. Кроме имен, они определяются одинаково в файле models.py.

Я нашел исправление, но я озадачен, почему это нужно сделать таким образом. Я оставил класс A и класс B в покое, и я переместил определение C и D в класс PropertiesFile.

class PropertiesFile(models.Model):

    class C(DisplayValuePair):
        pass

    class D(DisplayValuePair):
        pass

    # there lots of other foreign key fields that already exist in the model
    # that are defined the same way, but these are new. The fields used to all
    # be models.CharField
    my_a_field = models.ForeignKey(A, null=True, blank=True, on_delete=_PROTECT)
    my_b_field = models.ForeignKey(B, null=True, blank=True, on_delete=_PROTECT)
    my_c_field = models.ForeignKey(C, null=True, blank=True, on_delete=_PROTECT)
    my_d_field = models.ForeignKey(D, null=True, blank=True, on_delete=_PROTECT)

Если определение класса C и класса D находится внутри моделей. py файл, то как не удается разрешить использование этих классов в PropertiesFile, если я не перенесу их в PropertiesFile?

1 Ответ

0 голосов
/ 27 апреля 2020

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

...