首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >"id“字段的Django AutoField错误迁移

"id“字段的Django AutoField错误迁移
EN

Stack Overflow用户
提问于 2015-06-23 17:15:48
回答 1查看 3.4K关注 0票数 0

我有非常简单的Django模型:

代码语言:javascript
复制
class MyModel(models.Model):
    user = models.ForeignKey(User)
    somestring = models.CharField(
        max_length=250
    )
   ... some other string fields...

模型中没有声明的"id“字段,因此它具有Django分配的自动主键。

最初的迁移情况如下:

代码语言:javascript
复制
migrations.CreateModel(
    name='MyModel',
    fields=[
         ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
         ('somestring', models.CharField(max_length=250))
         ... some other string fields...
    ],
    options={},
    bases=(models.Model,),
),

它已成功应用,数据库表包含以下字段:

代码语言:javascript
复制
- id   <== autogenerated 
- user
- somestring
 etc...

偶尔我会收到这样的消息

代码语言:javascript
复制
Your models have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

在运行manage.py makemigrations之后,它生成了非常奇怪的迁移:

代码语言:javascript
复制
$ ./manage.py makemigrations
You are trying to add a non-nullable field 'id' to mymodel without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows)
 2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now()
>>> 
Please enter some code, or 'exit' (with no quotes) to exit.
>>> ''
Migrations for 'myapp':
  0036_auto_20150623_1535.py:
    - Add field id to mymodel

就像这样:

代码语言:javascript
复制
class Migration(migrations.Migration):

    dependencies = [
        ('foo', 'bar'),
    ]

    operations = [
        migrations.AddField(
            model_name='mymodel',
            name='id',                 <== !!!
            field=models.AutoField(auto_created=True, primary_key=True, default='', serialize=False, verbose_name='ID'),
            preserve_default=False,
        ),
    ]

但是这种迁移没有意义,而且肯定会失败,因为在适当的DB表中已经有了"id“字段。

快速而肮脏的解决方案是-伪造这个迁移。它应该在dev机器上本地工作,但在其他环境中可能会导致迁移错误(测试/暂存/prod)。

看起来模型的旧/新字段状态计算错误,因此"id“不包含在旧模型中,而是包含在新模型中,因此django取消了应该添加id字段。

不清楚原因,但我的主要问题是-在没有必要迁移的情况下,重新设置模型或迁移状态并将其返回到以前的状态的正确方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-24 06:53:57

好吧,找到一个可行的解决办法。

在原始迁移中添加了"id“字段声明,因此不再报告丢失。

代码语言:javascript
复制
migrations.CreateModel(
    name='MyModel',
    fields=[
!!===>   ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
         ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
         ('somestring', models.CharField(max_length=250))
         ... some other string fields...
    ],
    options={},
    bases=(models.Model,),
),

这种更改不会应用于已经进行迁移的环境,新的环境应该从一开始就得到正确的db表结构。

TIL: Django不使用从DB获取当前模型状态,而是创建模型的模拟,并将迁移应用到该模拟,直到根据所有可用的迁移操作获得模型的最新版本为止。然后将该重构模型与models.py的实模型进行了比较。

调整原迁移解决了这一问题。感谢参加讨论的每一个人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31009279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档