So some time a couple migrations after my first one, I decided I wanted to include these fields:
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
into one of my models. When I makemigrations
it gave me
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).
So I then changed it to
created = models.DateTimeField(auto_now_add=True, default=datetime.now)
After trying to makemigrations
again, it said that 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.
All right, so I just went ahead and removed the auto_now_add
created = models.DateTimeField(default=datetime.now)
I could now makemigrations
without any problems. And then I later removed default=datetime.now
and replaced it with auto_now_add=True
, and migrated again without any problems. However, I can't help feeling that this might not be the best way of doing things. I feel like something might go wrong later in the project.
To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB. Save this answer.
you can either: temporarily remove your migration, execute python manage.py migrate, add again your migration and re-execute python manage.py migrate. Use this case if the migrations refer to different models and you want different migration files for each one of them.
Move the already done migrations from that file into the empty migration you created.. then --fake that one. This will put Django's understanding of what the database looks like will be in sync with reality and you can then migrate as normal, applying the changes in the last migration file.
Since version 1.7, Django has come with built-in support for database migrations. In Django, database migrations usually go hand in hand with models: whenever you code up a new model, you also generate a migration to create the necessary table in the database. However, migrations can do much more.
I think the best practice here would have been to make the fields nullable. What your created
field means at the moment is: "The time when the instance was created, or the arbitrary time when I ran the migration." The standard way to represent the lack of a value is NULL
, rather than an arbitrary value.
That said, if you do want to use some arbitrary value you just need to tell Django what it is. Usually makemigrations
gives you the option to indicate a one-off value to use for existing rows - did that not happen?
A more laborious method would be to declare the field nullable, then create a data migration to fill in your desired value, and then make it non-nullable. What you did is basically a simplified version of that. I don't see it creating any problems moving forward other than the issue of created
not really being the time the instance was created.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With