Skip to main content
 首页 » 编程设计

python之Django 1.11 模型迁移操作不适用

2024年09月03日32JeffreyZhao

我在迁移中的操作已执行,而与付款人字段相关的数据库没有任何变化。

这是我的模型:

class User(AbstractBaseUser, PermissionsMixin, WithCsvImportMixin): 
    first_name = models.CharField(_('first name'), max_length=30, blank=False) 
    last_name = models.CharField(_('last name'), max_length=30, blank=False) 
    email = models.EmailField(_('email address'), 
                              unique=True, blank=False) 
    external_id = models.CharField(_('external id'), db_index=True, max_length=50, unique=True, blank=False, null=True) 
    is_staff = models.BooleanField(_('staff status'), default=False) 
    is_active = models.BooleanField(_('active'), default=True) 
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now) 
    payer = models.CharField(_('payer'), max_length=50, blank=False, default='') 

关于payer字段的第一次迁移:

# -*- coding: utf-8 -*- 
# Generated by Django 1.11.6 on 2018-11-15 21:58 
from __future__ import unicode_literals 
 
from django.db import migrations, models 
 
 
class Migration(migrations.Migration): 
 
    dependencies = [ 
        ('authenticate', '0012_auto_20181112_1631'), 
    ] 
 
    operations = [ 
        migrations.AddField( 
            model_name='user', 
            name='payer', 
            field=models.CharField(default='', max_length=50, verbose_name='payer'), 
        ), 
    ] 

这是执行的那个,但结果似乎没有应用到数据库:

# -*- coding: utf-8 -*- 
# Generated by Django 1.11.6 on 2018-11-15 22:01 
from django.db import migrations, transaction 
 
from xxx.authenticate.models import User # The xxx is here to replace the actual application name 
 
def create_payer_names(apps, schema_editor): 
    with transaction.atomic(): 
        for user in User.objects.all(): 
            if user.external_id != "": 
                user.payer = user.external_id 
                user.save() 
 
class Migration(migrations.Migration): 
 
    dependencies = [ 
        ('authenticate', '0013_user_payer'), 
    ] 
 
    operations = [ 
        migrations.RunPython(create_payer_names, migrations.RunPython.noop, atomic=True), 
    ] 

我的数据库已经填充,每个用户都有一个 external_id

>>> from xxx.authenticate.models import User 
>>> for item in User.objects.all(): 
...     print(item.external_id) 
...  
043819FZAFR 
762944FZAFR 
285895FZAFR 
671800FZAFR 
924618FZAFR 
068805FZAFR 
232544FZAFR 
130978FZAFR 
412568FZAFR 
600003FZAFR 
254624FZAFR 
417745FZAFR 
068280FZAFR 
031971FZAFR 
141936FZAFR 
>>>  

这是之前迁移的空结果:

>>> for item in User.objects.all(): 
...     print(item.payer) 
...  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
>>>  

这是命令的输出:manage.py showmigrations

authenticate 
 [X] 0001_initial 
 [X] 0002_auto_20171103_1722 
 [X] 0003_auto_20171109_1206 
 [X] 0004_auto_20180329_1049 
 [X] 0005_auto_20180507_1123 
 [X] 0006_user_by_pass_generates_invoice 
 [X] 0007_auto_20180524_1732 
 [X] 0008_auto_20180530_1525 
 [X] 0009_auto_20180801_1644 
 [X] 0010_user_payment 
 [X] 0011_remove_user_payment 
 [X] 0012_auto_20181112_1631 
 [X] 0013_user_payer 
 [X] 0014_auto_20181115_2301 

当我这样做时:

./manage.py migrate authenticate 0014 

输出如下:

Running migrations: 
  No migrations to apply. 

有人可以向我解释我做错了什么以及为什么没有按预期应用迁移操作吗?

请您参考如下方法:

在迁移中,您应该使用apps.get_model 来获取User 模型。有关详细信息,请参阅有关 [数据迁移] 的文档。

def create_payer_names(apps, schema_editor): 
    User = apps.get_model('authentication', 'User') 
    with transaction.atomic(): 
        ... 

showmigrations 的输出显示已应用迁移 0014。这就是您收到 No migrations to apply 消息的原因。

 [X] 0014_auto_20181115_2301 

您可以先伪装回 0013 迁移来重新运行 0014 迁移。

./manage.py migrate --fake authenticate 0013 
./manage.py migrate authenticate 0014