Миграция Django с «--fake-initial» не работает, если AddField ссылается на «тот же» столбец - PullRequest
0 голосов
/ 30 сентября 2018

Я играю с django (я совсем новичок), и, читая веб-страницы, я прочитал, что можно было бы сохранить наши внутренние соглашения о присвоении имен camelCase в базе данных mySQL, а также для названия моделей внутри моделей.py

Что ж, через несколько дней я могу сделать вывод, что лучше оставить все как есть и использовать стандартный вывод, сгенерированный inspectdb, без каких-либо изменений в его коде (я удалил функции .lower(): -))

Во всяком случае, просто из любопытства, я был бы признателен, если кто-нибудь может объяснить мне, почему то, что следует, не работает.Вкратце, мне кажется, что код, ответственный за миграцию, не проверяет правильно (?), Если имя столбца уже находится внутри базы данных, или, по крайней мере, делает его сравнение с учетом регистра.Это по замыслу?

Я использую это руководство из интернета https://datascience.blog.wzb.eu/2017/03/21/using-django-with-an-existinglegacy-database/

MySQL работает с опцией " --lower-case-table-names=0", и сортировка не чувствительна к регистру.

Внутри models.py У меня есть это

class City(models.Model):
    id = models.AutoField(db_column='ID', primary_key=True)
    name = models.CharField(db_column='Name', max_length=35)
    countrycode = models.ForeignKey(Country, db_column='CountryCode')
    district = models.CharField(db_column='District', max_length=20)
    population = models.IntegerField(db_column='Population', default=0)

    def __str__(self):
        return self.name

    class Meta:
        managed = True
        db_table = 'city'
        verbose_name_plural = 'Cities'
        ordering = ('name', )

, если я изменяю ссылку 'db_column' на db_column='countryCode' (обратите внимание на нижнюю букву "c"), и я запускаю

./manage.py migrate --database world_data --fake-initial worlddata

Я получаю сообщения об ошибках: 'django.db.utils.OperationalError: (1050, "таблица' city 'уже существует") "

, и проблема возникает только при использовании опции --fake-initial

После анализа "... django / db / migrations / executor.py" я нашел те строки, которые проверяют, находится ли столбец уже внутри существующего

column_names = [
    column.name for column in
    self.connection.introspection.get_table_description(self.co$
]
if field.column not in column_names:
    return False, project_state

здесь, насколько я понимаю, нетсравнение с учетом регистра, поэтому столбец "countryCode" не найден внутри "column_names":

-> if field.column not in column_names:
(Pdb) field.column
'countryCode'
(Pdb) column_names
['ID', 'Name', 'CountryCode', 'District', 'Population']

1 Ответ

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

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


Итак, сначала давайте разберемся.Вы упоминаете, что --lower-case-table-names=0 включен, но сортировка нечувствительна к регистру. Из документов Я вижу, что эта опция вызывает чувствительность к регистру имен таблиц.Я мог бы просто читать это неправильно, но похоже, вы говорите, что все должно быть без учета регистра.Кроме того, сортировка обычно относится к самим данным, а не к именам столбцов, если вы не знаете.

Тем не менее, насколько я знаю, все базы данных обрабатывают имена столбцов без учета регистра (я только что проверил в SQLite), так что вывозможно, только что обнаружил ошибку в Django!Я просмотрел историю файла, и за 5 с лишним лет этот код существовал, я думаю, никто не сталкивался с этой проблемой.Это понятно, так как обычно люди либо а) просто позволяют django создавать БД с нуля и, таким образом, все синхронизируется, либо б) они используют inspectdb для генерации кода с правильным регистром для столбцов.

ЭтоПохоже, вы просто играли вокруг, поэтому я не думаю, что вы ищете конкретное решение.Возможно, следующий шаг - сообщить об ошибке ;)?Из того, что я вижу, не было бы никакого недостатка в добавлении сравнения без учета регистра, но у парней, работающих над Django 24/7, может быть другое мнение.

...