Джанго продолжает мигрировать тот же внешний ключ - PullRequest
0 голосов
/ 17 октября 2018

Я импортирую существующую базу данных в собственный проект Django.Я сгенерировал исходные модели из базы данных через inspectdb и позволяю Django управлять каждой таблицей по одной, комментируя строки managed=False в мета-настройках таблицы.Я начал с простых моделей и затрудняю работу с таблицами с внешними ключами.Django продолжает генерировать ту же миграцию для внешнего ключа DocTagID, и я не уверен, почему он это делает?

Таблица ниже показана ниже, все генерируется inspectdb за исключениемзакомментированной строки, в которой я передаю управление таблицей Django.

class Doctagversion(models.Model):
    id = models.IntegerField(db_column='Id', primary_key=True, blank=True)  # Field name made lowercase.
    doctagid = models.ForeignKey(DocTag, models.DO_NOTHING, db_column='DocTagId')  # Field name made lowercase.
    groupname = models.TextField(db_column='GroupName')  # Field name made lowercase.
    name = models.TextField(db_column='Name')  # Field name made lowercase.
    creationdate = models.DateTimeField(db_column='CreationDate')  # Field name made lowercase.
    lasteditdate = models.DateTimeField(db_column='LastEditDate', blank=True, null=True)  # Field name made lowercase.
    lastedituserid = models.IntegerField(db_column='LastEditUserId')  # Field name made lowercase.
    lastedituserdisplayname = models.TextField(db_column='LastEditUserDisplayName')  # Field name made lowercase.
    releasedate = models.DateTimeField(db_column='ReleaseDate', blank=True, null=True)  # Field name made lowercase.

    class Meta:
#         managed = False
        db_table = 'DocTagVersion'

Перед передачей этого элемента управления начальная миграция для рассматриваемой схемы создается с использованием python -m manage.py makemigrations и применяется с python -m manage.py migrate.Эта начальная миграция для таблицы выглядит следующим образом: managed изначально установлен на False, и закомментированная строка является записью, которую, я полагаю, я должен добавить, чтобы сообщить Django о внешнем ключе (inspectdb указывает столько же в сгенерированном models.py).

    migrations.CreateModel(
        name='Doctagversion',
        fields=[
            ('id', models.IntegerField(blank=True, db_column='Id', primary_key=True, serialize=False)),
            # ('doctagid',models.ForeignKey(db_column='DocTagId', default=-1, on_delete=models.deletion.DO_NOTHING, to='DocTag')),
            ('groupname', models.TextField(db_column='GroupName')),
            ('name', models.TextField(db_column='Name')),
            ('creationdate', models.DateTimeField(db_column='CreationDate')),
            ('lasteditdate', models.DateTimeField(blank=True, db_column='LastEditDate', null=True)),
            ('lastedituserid', models.IntegerField(db_column='LastEditUserId')),
            ('lastedituserdisplayname', models.TextField(db_column='LastEditUserDisplayName')),
            ('releasedate', models.DateTimeField(blank=True, db_column='ReleaseDate', null=True)),
        ],
        options={
            'db_table': 'DocTagVersion',
            'managed': False,
        },
    ),

Когда я включаю контроль над таблицей, первая миграция просто меняет параметры таблицы.

    migrations.AlterModelOptions(
        name='doctagversion',
        options={},
    ),

Django добавляет рассматриваемый внешний ключ, если его нет вначальная миграция выглядит следующим образом.

    migrations.AddField(
        model_name='doctagversion',
        name='doctagid',
        field=models.ForeignKey(db_column='DocTagId', default=-1, on_delete=django.db.models.deletion.DO_NOTHING, to='docutoo.DocTag'),
        preserve_default=False,
    ),

После этого он многократно генерирует следующую миграцию в виде одного цикла между python m manage.py makemigrations и python -m manage.py migrate.

    migrations.AlterField(
        model_name='doctagversion',
        name='doctagid',
        field=models.ForeignKey(db_column='DocTagId', on_delete=django.db.models.deletion.DO_NOTHING, to='docutoo.DocTag'),
    ),

Возможно, моя стратегия неверна, и яследует просто включить все таблицы за одну миграцию?

Насколько я могу судить, следующие связанные вопросы не учитывают мою ситуацию:

1 Ответ

0 голосов
/ 17 октября 2018

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

  class Meta : 
    ...
#     db_table = "TableName"

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

В сторону

По совпадению, когда создается начальная миграция для существующей базы данных, как описано в моем вопросе (inspectdb -> makemigrations -> migrate),Джанго обходит модели в алфавитном порядке, создавая таблицы в одинаковом порядке и игнорируя внешние ключи.Он создает таблицы в алфавитном порядке, а затем изменяет их позже, чтобы включить внешние ключи, что приводит к засорению любых данных, которые могут присутствовать в существующей базе данных.Кажется, нужно сначала определить внешние ключи как целочисленные поля и вернуть их обратно, так как Django позволяет управлять таблицами.В качестве альтернативы можно закомментировать все их модели и сгенерировать миграцию, когда кто-то раскомментирует их способом, который разрешает внешние ключи;Затем Джанго свяжет их соответственно.Затем можно объединить миграции в одну миграцию и установить ее в качестве начальной миграции.

...