Django 1.8 迁移。在数据库创建后添加 DateTimeField。最佳实践?
Django 1.8 Migrations. Adding DateTimeField after db creation. Best practices?
所以在我第一次迁移之后的一段时间里,我决定要包括这些字段:
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
进入我的一个模型。当我 makemigrations
它给了我
You are trying to add a non-nullable field 'created' to episode without a default; we can't do that (the database needs
something to populate existing rows).
所以我将其更改为
created = models.DateTimeField(auto_now_add=True, default=datetime.now)
再次尝试makemigrations
后,它说at_api.Episode.modified: (fields.E160) The options auto_now, auto_now_add, and default are mutually exclusive. Only one
of these options may be present.
好的,所以我继续删除 auto_now_add
created = models.DateTimeField(default=datetime.now)
我现在 makemigrations
没有任何问题。然后我后来删除了 default=datetime.now
并用 auto_now_add=True
替换了它,并且再次迁移没有任何问题。但是,我不禁觉得这可能不是最好的做事方式。我觉得项目后期可能会出问题。
我认为这里的最佳做法是让字段可以为空。您的 created
字段目前的含义是:"The time when the instance was created, or the arbitrary time when I ran the migration." 表示缺少值的标准方法是 NULL
,而不是任意值。
就是说,如果您确实想使用某个任意值,您只需要告诉 Django 它是什么。通常 makemigrations
为您提供了指示一次性值用于现有行的选项 - 这没有发生吗?
一种更费力的方法是声明该字段可为空,然后创建数据迁移以填充您想要的值,然后使其不可为空。你所做的基本上是它的简化版本。除了 created
不是真正创建实例的时间之外,我认为它不会产生任何问题。
我刚刚遇到了确切的问题。我使用 Django 1.10。我读了 Kevin 的回答,当 Django 要求我将其填充为 datetime.now
字符串时,我试图设置默认值。
我很惊讶,因为对于这些字段,Django 会自动询问您是否要使用 datetime.now
作为默认值:
$ ./manage.py makemigrations
You are trying to add the field 'date_created' with 'auto_now_add=True' to projectasset without a default; the database needs something to populate existing rows.
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
You can accept the default 'timezone.now' by pressing 'Enter' or you can provide another value.
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
[default: timezone.now] >>>
所以,我只是确认一下,一切似乎都正常!
所以在我第一次迁移之后的一段时间里,我决定要包括这些字段:
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
进入我的一个模型。当我 makemigrations
它给了我
You are trying to add a non-nullable field 'created' to episode without a default; we can't do that (the database needs
something to populate existing rows).
所以我将其更改为
created = models.DateTimeField(auto_now_add=True, default=datetime.now)
再次尝试makemigrations
后,它说at_api.Episode.modified: (fields.E160) The options auto_now, auto_now_add, and default are mutually exclusive. Only one
of these options may be present.
好的,所以我继续删除 auto_now_add
created = models.DateTimeField(default=datetime.now)
我现在 makemigrations
没有任何问题。然后我后来删除了 default=datetime.now
并用 auto_now_add=True
替换了它,并且再次迁移没有任何问题。但是,我不禁觉得这可能不是最好的做事方式。我觉得项目后期可能会出问题。
我认为这里的最佳做法是让字段可以为空。您的 created
字段目前的含义是:"The time when the instance was created, or the arbitrary time when I ran the migration." 表示缺少值的标准方法是 NULL
,而不是任意值。
就是说,如果您确实想使用某个任意值,您只需要告诉 Django 它是什么。通常 makemigrations
为您提供了指示一次性值用于现有行的选项 - 这没有发生吗?
一种更费力的方法是声明该字段可为空,然后创建数据迁移以填充您想要的值,然后使其不可为空。你所做的基本上是它的简化版本。除了 created
不是真正创建实例的时间之外,我认为它不会产生任何问题。
我刚刚遇到了确切的问题。我使用 Django 1.10。我读了 Kevin 的回答,当 Django 要求我将其填充为 datetime.now
字符串时,我试图设置默认值。
我很惊讶,因为对于这些字段,Django 会自动询问您是否要使用 datetime.now
作为默认值:
$ ./manage.py makemigrations
You are trying to add the field 'date_created' with 'auto_now_add=True' to projectasset without a default; the database needs something to populate existing rows.
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
You can accept the default 'timezone.now' by pressing 'Enter' or you can provide another value.
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
[default: timezone.now] >>>
所以,我只是确认一下,一切似乎都正常!