I am working with Postgres on a Django app and I want to make a model change, resetting a row so it is no longer the primary key.
This is what my model currently looks like in Django:
class Meeting(TimeStampedModel):
row = models.CharField(max_length=20, primary_key=True)
total_items = models.IntegerField()
I have run django-admin.py flush
to remove all data from the database. If I run python manage.py makemigrations
I see No changes detected
. So we are starting from a clean base.
Now I edit row
in models.py so it is no longer the primary key:
row = models.CharField(max_length=20)
And run python manage.py makemigrations
and set 1
as the default when asked:
You are trying to add a non-nullable field 'id' to meeting 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()
>>> 1
Migrations for 'frontend':
0007_auto_20150305_1129.py:
- Add field id to meeting
- Alter field row on meeting
That seems to run OK. Then if I run python manage.py migrate
:
$ python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: debug_toolbar
Apply all migrations: contenttypes, frontend, sites, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Installing custom SQL...
Installing indexes...
Running migrations:
Applying frontend.0007_auto_20150305_1129...Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/Users/me/.virtualenvs/meetings/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
...
File "/Users/me/.virtualenvs/meetings/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: multiple default values specified for column "id" of table "frontend_meeting"
Why is it telling me I have multiple default values
?
Do I need to set a unique primary key value as a default - and if so, how can I do this?
This is what the migrations file looks like:
class Migration(migrations.Migration):
dependencies = [
('frontend', '0006_auto_20150305_1050'),
]
operations = [
migrations.AddField(
model_name='meeting',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, default=1, serialize=False, verbose_name='ID'),
preserve_default=False,
),
migrations.AlterField(
model_name='meeting',
name='row',
field=models.CharField(max_length=20),
preserve_default=True,
),
]
1. Run makemigrations to verify if your schema and your database are identical, but if our local initial migration is differs from the one that was applied to the database , Django won't let us know of this, and it'll say that is all good, but because of that, the local differences that you have won't be applied. 2.
There is only one file in migration folder that you should not ignore. That file is init.py file, If you ignore it, python will no longer look for submodules inside the directory, so any attempts to import the modules will fail.
--fake-initialAllows Django to skip an app's initial migration if all database tables with the names of all models created by all CreateModel operations in that migration already exist. This option is intended for use when first running migrations against a database that preexisted the use of migrations.
Try to use an intermediate migration to achieve this:
1) Add id = models.IntegerField()
to your model.
Run makemigrations and then migrate.
2) Remove primary_key=True from the 'row'-field, and also remove the 'id'-field. Again run makemigrations and migrate.
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