我有非常简单的Django模型:
class MyModel(models.Model):
user = models.ForeignKey(User)
somestring = models.CharField(
max_length=250
)
... some other string fields...模型中没有声明的"id“字段,因此它具有Django分配的自动主键。
最初的迁移情况如下:
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,),
),它已成功应用,数据库表包含以下字段:
- id <== autogenerated
- user
- somestring
etc...偶尔我会收到这样的消息
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之后,它生成了非常奇怪的迁移:
$ ./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就像这样:
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字段。
不清楚原因,但我的主要问题是-在没有必要迁移的情况下,重新设置模型或迁移状态并将其返回到以前的状态的正确方法是什么?
发布于 2015-06-24 06:53:57
好吧,找到一个可行的解决办法。
在原始迁移中添加了"id“字段声明,因此不再报告丢失。
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的实模型进行了比较。
调整原迁移解决了这一问题。感谢参加讨论的每一个人。
https://stackoverflow.com/questions/31009279
复制相似问题