Я столкнулся с этой потребностью в нашей существующей инфраструктуре.
Весь наш бэкэнд полагался на модель пользователя по умолчанию в Django, но нам нужно было изменить этот max_len, чтобы он соответствовал адресу электронной почты max_len.
Из большинства постов StackOverflow, которые я видел, люди в основном рекомендуют создавать пользовательские модели пользователей.Это было определенно то, чего мы должны были избежать в нашем случае.Переход от модели пользователя по умолчанию к пользовательской является серьезной и сложной операцией, когда выполняется на сотнях тысяч работающих пользователей.
Таким образом, вместо этого мы просто хотели напрямую применить изменение к самой схеме базы данных.,Чтобы сделать это правильно, лучше всего выполнить переход от миграции.Однако я не смог найти способ напрямую сгенерировать миграцию для модели User.
Один из способов, который я увидел, - сгенерировать пустую миграцию, а затем использовать необработанный SQL для выполнения миграции.
Создание пустой миграции:
python manage.py makemigrations YOUR_APP --empty
Редактирование миграции:
# -*- coding: utf-8 -*-
# Generated by Django 1.10.6 on 2019-02-11 09:39
from __future__ import unicode_literals
from django.db import migrations, models
from django.db.models import F
from django.db.models.functions import Length
from pittsburgh.models import User
#
# This function fixes thee existing user records by applying setting their username to be their email
#
def forwards_func_username(apps, schema_editor):
User.objects.annotate(email_len=Length('email')).filter(email_len__gte=30).update(username=F('email'))
#
# This function reverts back to the original state
# Users with email > 30 chars have their username being a truncated email
#
def reverse_func_username(apps, schema_editor):
users = User.objects.annotate(email_len=Length('email')).filter(email_len__gte=30)
for user in users:
user.username = user.email[:30]
user.save()
class Migration(migrations.Migration):
dependencies = [
('pittsburgh', '0076_auto_20190205_1623'),
]
operations = [
# change username max_length from 30 to 75 to match email max max_length
migrations.RunSQL(sql="ALTER TABLE auth_user MODIFY COLUMN username VARCHAR(75) NOT NULL;",
reverse_sql="ALTER TABLE auth_user MODIFY COLUMN username VARCHAR(30) NOT NULL;"),
# update username to match email
migrations.RunPython(forwards_func_username, reverse_func_username),
]
forwards_func_username
и reverse_func_username
из RunPython
являются необязательными, зависит от того, что вы готовыdo.
Обратите внимание, что для RunSQL
требуется зависимость sqlparse
, поэтому не забудьте добавить ее в свой файл requirements.txt
.
sqlparse==0.2.4 # used implicitly by Django Migrations engine when using RunSQL operation
Надежды, которые помогают, япотратил пару часов, просматривая веб-страницы, чтобы найти какое-то хорошее решение, но Django серьезно разработал эту часть (к примеру, очень не хватает простого и понятного дизайна, доступного в Ruby on Rails).