Python 2 -> 3 Django вызывает изменение типа параметра поля - PullRequest
0 голосов
/ 28 августа 2018

Мы переводим проект Django с Django 1.8 -> 2.1 и Python 2.7 -> 3.6.

В старой версии проекта есть модели Django, которые выглядели так, например:

# models.py

from django.db import models

class RowStatusModel(models.Model):
    active = models.BooleanField(default=True, db_column='is_active')
    # ...
    class Meta:
        abstract = True

Обратите внимание, что from __future__ import unicode_literals не , используемый в этом модуле. Это означает, что db_column - это Python 2 str, соответствующий bytes в Python 3. Начальная миграция, 0001_initial.py, выглядит следующим образом:

# 0001_initial.py

operations = [
    # ...
    ('row_ef', models.BooleanField(default=True, db_column=b'is_active')
    # ...
]

Обратите внимание на байтовый литерал b'is_active, который, как я полагаю, был сделан Джанго в целях большей ясности, но я не уверен.

Теперь, после перехода большей части кодовой базы с 2to3 и выполнения makemigrations, Python 3 обрабатывает строковый литерал как то, что будет типом Unicode в Python 2, и, следовательно, генерирует миграцию, где db_column является строковым литералом, для каждой модели, которая наследуется от RowStatusModel:

# migrations/0023_auto_20180827_1955.py 
migrations.AlterField(
    # ...
    field=models.BooleanField(default=True, db_column='is_active')
), # ...

Какой эффект, если таковой имеется , будет иметь это на стороне базы данных при запуске ./manage.py migrate? Является ли «изменение» чисто на стороне Python, или какие побочные эффекты могут быть созданы?


Движок базы данных: django.db.backends.postgresql.


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

1 Ответ

0 голосов
/ 28 августа 2018

Я наткнулся на билет Django после того, как задал этот вопрос, где разработчик Django рекомендует редактировать любые устаревшие файлы миграции (например, 0001_initial), которые содержат (Python 3) байтовые литералы, удаляя b и создание их строковых литералов в Python 3.

Редактирование миграций для устранения этой проблемы безопасно.

Оттуда вы, вероятно, должны иметь возможность удалить модули миграции, созданные с помощью python3 ./manage.py makemigrations, и повторить эту команду, которая больше не должна иметь проблем с типом этого аргумента.

Я использовал следующее для массового поиска и замены всех экземпляров 'db_column=b' на 'db_column='. Конечно, вы должны обязательно проверить git diff перед тем, как сделать этот коммит.

grep -nrl "db_column=b" apps | xargs sed -i "s/db_column=b/db_column=/g"
...