I am trying to apply a migration but am getting the error:
django.db.utils.OperationalError: (1050, "Table 'customers_customer'
already exists")
I get this by issuing the following command:
python manage.py migrate
My customer table already exists, so what do I do to let the migration know this, not error out, and run my modification to my model?
I ran this on my local environment with local database with no problem. It is when I pointed my database to production and ran migrate above that I get this error.
If you have the table created in the database, you can run
python manage.py migrate --fake <appname>
Mark migrations as run without actually running them
Or if you want to avoid some actions in your migration, you can edit the migration file under the app/migrations directory and comment the operations you don't want to do in the migrate execution.
Docs: https://docs.djangoproject.com/en/1.8/topics/migrations/#upgrading-from-south
or python manage.py help migrate
Its actually python manage.py migrate --fake <appname>
We can solve this issue in two way as mentioned in answer:
1.) By editing in migration file
We have migrations folder created in each application we create, In
those migration folder the migration file(0001_initial.py is the
initially created and after this all other files dependent on this
initial file will be create), When we run the python manage.py
migrate, For every APP the migration file will apply if there is
change in the file. We can see this run Applying on terminal after the
migrate command. If there is any issue in migration file we use to get
the error at that point. In my/our case:
Applying ValetUser.0002_keyroundslots_systemparameters_vehicleparking_vehicleparkingdetails...Traceback (most recent call last):
sqlite3.OperationalError: table "valet_keyroundslots" already exists
Here we can notice that the file in which we have issue is mentioned
i.e ValetUser.0002_keyroundslots_systemparameters, So we can Go to the
App and then migrations and in 0002 file we can Comment the
CreateModel Operation of That particular Model in which we are facing issue while
applying migrations.
example:
operations = [
# migrations.CreateModel(
# name='KeyRoundSlots',
# fields=[
# ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
# ('key_round', models.IntegerField()),
# ('key_slot', models.IntegerField()),
# ('is_available', models.BooleanField()),
# ('Valet_id', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='valet_location', to='ValetUser.ValetAt')),
# ],
# options={
# 'db_table': 'valet_keyroundslots',
# },
# ),
2.) By applying fake migration of the modified migration file of the particular APP in which we are facing the error/issue, --fake will
apply the fake migration that will not effect to the already applied
migration of the model.
python manage.py migrate --fake <appname>
The answers given Waqas and elmonkeylp are also right, I just wanna
explain it in brief with the help of we use to scenario
Related
I currently have a database using Heroku and want to migrate it to AWS, where both use PostgresSQL. So, after some digging on how to get it done I followed the steps as on this youtube video.
I initially ran python manage.py dumpdata > dumpdata.json with my Heroku database credentials in Django.
Afterwards, I changed my database credentials in settings.py to the AWS database credentials, and ran python manage.py migrate --run-syncdb which worked successfully.
And then I ran the code python manage.py loaddata dumpdata.json, when where I was thrown an error.
The following error came up:
django.db.utils.IntegrityError: Problem installing fixture 'C:\Users\Acer\Desktop\Web Development\Proffesional\eblossom\eblossom\eblossom\dumpdata.json': Could not load contenttypes.ContentType(pk=9): duplicate key value violates unique constraint "django_content_type_app_label_model_76bd3d3b_uniq"
DETAIL: Key (app_label, model)=(user, profile) already exists.
I don't understand what has gone wrong over here, the site is working perfectly fine all this time with no database compilation error, but now when I try to migrate it to AWS, I am thrown with this problem.
Just in case my models.py:
class Profile (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
mobile_number = models.CharField(max_length=12, null=True)
guest = models.BooleanField(default=False)
def __str__(self):
return f"{self.user}"
I do this all the time between databases, local and remote, postgres or sqlite.
In order to achieve that, do the following steps in order :
# Start the same as you did on local database
python manage.py dumpdata > db.json
# push this file to your production/server location
# and delete or start with a fresh new database
python manage.py migrate
python manage.py shell
# Enter the following in the shell
from django.contrib.contenttypes.models import ContentType
ContentType.objects.all().delete()
# Exit shell and run following command
python manage.py loaddata db.json
I am making changes to a model AppContactCnt to add new fields to handle deleting of records.
Here is that models.py
class AppContactCnt(models.Model):
id_cnt = models.AutoField(primary_key=True)
# idcst_cnt = models.IntegerField()
idcst_cnt = models.ForeignKey(AppCustomerCst, models.DO_NOTHING, db_column='idcst_cnt')
idctp_cnt = models.ForeignKey(AppContactTypeCtp, models.DO_NOTHING, db_column='idctp_cnt')
idtrp_cnt = models.IntegerField()
name_cnt = models.CharField(max_length=50)
phone_cnt = models.CharField(max_length=50, blank=True, null=True)
email_cnt = models.CharField(max_length=100, blank=True, null=True)
note_cnt = models.CharField(max_length=100, blank=True, null=True)
receives_emails_cnt = models.BooleanField(blank=True, null=True)
deleted_cnt = models.BooleanField(blank=True, null=True)
# date_deleted_cnt = models.DateTimeField(blank=True, null=True)
# deleted_by_cnt = models.CharField(max_length=100, blank=True, null=True)
class Meta:
db_table = 'app_contact_cnt'
app_label = 'easytrade20'
I tried to add in managed = True no change.
Also tried the following:
Delete all previous migration files and pycache files except init.
python manage.py migrate --fake-initial
python manage.py makemigrations
python manage.py migrate
I am still getting No changes detected
I am not sure how to proceed, any assistance is apprecaited.
You have set app_label = 'easytrade20' in the meta option, but Django is unable to detect an app named easytrade20 in your project. That's why there aren't any changes.
So, add easytrade20 to your INSTALLED_APPS or remove app_label = 'easytrade20' from the model's Meta, and try again to run your migrations.
try this:
python manage.py makemigrations [app_name]
python manage.py migrate
Problem
The app is likely not listed in INSTALLED_APPS located in settings.py, therefore Django has not registered your application and will not detect migrations that need to be run in that application.
Solution
Add easytrade20 to your INSTALLED_APPS and try again to run your migrations.
If the answers above didn't work for you I propose you to make a model and migrations based on an existing database. The steps to complete this task are outlined below.
Below I suggests that your app directory also called easytrade20.
I think that you already have a database that you are working with and all migrations have been applied to it. If not, and saving the
structure of migrations is not critical for you, then skip steps 2-3.
If any of your other apps have migrations that depend on easytrade20 migrations you need to repeat steps 2-5 for every of them (by renaming easytrade20 to your app name) before starting step 6 (and 6+ steps are required for that apps too).
0. Backup your files and database before changes
1. Update your Django version to the latest release
pip install django==3.0.* -U for 3.0.X (3.0.10 is latest release when I write these lines)
or
pip install django==3.1.* for latest one (3.1 have not so much differences from 3.0 and maybe it is right choice for you)
2. Check if all migrations are applied
Use showmigrations command to show applied migrations:
python manage.py showmigrations
You'll see structure with all apps and their migrations like this (app1 and app2 for example):
app1
[X] 0001_initial
app2
[X] 0001_initial
[X] 0002_some_other_migration
You'll see your apps and some django apps/third-party packages, like admin, auth, database, sessions etc.
If you'll see all [X] near every migration - all is fine, go on.
If you'll see some [ ] migration_name - try to apply these migrations first. Run python manage.py migrate app_name migration_name for every unapplied (unchecked) migration top down for every app (app_name for example).
3. Make new models based on your database structure
Use inspectdb to generate models:
python manage.py inspectdb > generated_models.py
File generated_models.py will be created. You need to copy from this file all models that you created for easytrade20 app. Replace your models.py with generated models and remove managed = False at least in the model AppContactCnt.
4. Remove information about easytrade20 migrations from database
python manage.py migrate --fake easytrade20 zero
And now if you'll run python manage.py showmigrations easytrade20 you'll see that all migrations unapplied.
5. Remove your migrations directory
That's it. Remove directory easytrade20/migrations completely.
Then if you'll run python manage.py showmigrations easytrade20 you'll see text (no migrations)
6. Generate new migrations
Run makemigrations command:
python manage.py makemigrations easytrade20
Folder easytrade20/migrations will be created. If not, then you'll need to check two things:
Your settings.py to ensure that easytrade20 included in your INSTALLED_APPS.
Your easytrade20 app settings. Ensure that your files have similar code:
# easytrade20/__init__.py
default_app_config = 'easytrade20.apps.EasyTradeConfig'
# easytrade20/apps.py
from django.apps import AppConfig
class EasyTradeConfig(AppConfig):
name = 'easytrade20'
7. Apply initial migration
If you have database with this table then fake migration:
python manage.py migrate easytrade20 --fake-initial
If not, then run without --fake-initial:
python manage.py migrate easytrade20
8. Make changes to your model, create and apply migrations
Change your models.py file.
Run python manage.py makemigrations easytrade20. New file in your easytrade20/migrations directory will be created.
Run python manage.py migrate easytrade20 to apply new migration.
Make sure your app is registered inside the settings.py, and the INSTALLED_APP section.
I initially created a database in mysql and used inspectdb to create all the models. So far so good, but then I started trying to make changes to the models and migrating them. I added columns to no avail, there were no changes in the database even though the migrations folder showed the changes. I began to wonder if it was something to do with case, so I tried again with a second model TestTwoT with table name and all fields in lower case. I then ran the make migrations which produced this output:
Migrations for 'testdb':
testdb/migrations/0010_testtwot.py
- Create model TestTwoT
The generated .py file in the migrations folder (which looks fine to me):
# Generated by Django 3.0.1 on 2020-02-10 22:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('testdb', '0009_auto_20200210_2241'),
]
operations = [
migrations.CreateModel(
name='TestTwoT',
fields=[
('id', models.AutoField(db_column='id', primary_key=True, serialize=False)),
('name', models.CharField(blank=True, db_column='name', max_length=1000, null=True)),
],
options={
'db_table': 'test_two_t',
'managed': True,
},
),
]
I then ran the migrate script which produced this output suggesting there were no problems creating the table:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, testdb, sessions
Running migrations:
Applying testdb.0010_testtwot... OK
However, still no sign of my new table when I run the 'show tables' sql command or the 'describe test_two_t' command.
There is another complication in my scenario in that I am not using the default database, but my setup seems entirely OK and my application is working fine pointing to the database.
EDIT : Following Borut's advice I changed the commands to (adding the --database parameter):
python3 manage.py makemigrations
python3 manage.py migrate --database=testdb
EDIT2 : It's all working perfectly now (after I also deleted all the previous migration .py files and started from scratch with the corrected above commands).
Following Borut's advice I changed the commands to (adding the --database parameter):
python3 manage.py makemigrations
python3 manage.py migrate --database=testdb
It's all working perfectly now (after I also deleted all the previous migration .py files and started from scratch with the corrected above commands).
I've discovered that I can set defaults for columns on a postgres database in a django project using migrations.RunSQL('some sql').
I'm currently doing this by adding a column, makemigrations, then removing the column, makemigrations, and then manually modifying the migration file that is produced.
I tried copying an old migration file and then removing the old code so just the new sql could be run and got some strange errors.
CommandError: Conflicting migrations detected; multiple leaf nodes in the migration graph: (0067_auto_20180509_2327, 0068_auto_20180514_0707 in csmu).
To fix them run python manage.py makemigrations --merge
How would you create a 'manual' django migration?
You can create a manual migration by running the command:
python manage.py makemigrations app_name --name migration_name --empty
Where app_name corresponds to the app within your project you want to add the migration. Remember Django manages both Project and Apps (A project is a collection of configuration and apps for a particular website. A project can contain multiple apps. An app can be in multiple projects.)
And --empty flag is to create a migration file where you will have to add your manual migrations.
For example, on a project where you have an app named api that only has one migration file 0001_initial.py running:
python manage.py makemigrations api --name migration_example --empty
will create a file named 0002_migration_example.py under the directory api/migrations/ that will look like:
# Generated by Django 2.2.10 on 2020-05-26 20:37
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
operations = [
]
And you should add migrations.RunSQL('some sql'). inside operations brackets, like:
operations = [
migrations.RunSQL('some sql')
]
You can learn how to make migrations by investigating the automatically generated migrations, for example:
class Migration(migrations.Migration):
dependencies = [
('app_details', '0001_initial'),
]
operations = [
migrations.AddField(
...,
),
migrations.CreateModel(
...,
),
migrations.RenameModel(
...,
),
migrations.RenameField(
...,
),
migrations.RemoveModel(
...,
),
# and so on
]
Create a manual migration file
use this command in the terminal: python manage.py makemigrations --empty.
Then add what you want in it.
notice: you have to compose between the "models.py" and the manual migrations.
I have been trying to synchronize changes to a model in a Django app using migrations in 1.7 (postgres 9.1 - let me know if you need more details of my environment), but manage.py migrate doesn't seem to do anything, and sqlmigrate doesn't emit any SQL.
I thought Django 1.7 - "No migrations to apply" when run migrate after makemigrations might be applicable to my situation, and I did find some history in the django_migrations table in my database. I deleted the records for the app I am trying to migrate.
Recently I gave up on getting the alter table statements to generate/run and dropped the original version of the table. And while manage.py migrate states it is applying the migration, nothing happens to the database.
Here are the steps I've been trying:
Delete the history.
rm -r myapp/migrations
../manage.py dbshell
myapp_db=> delete from django_migrations where app='myapp'
Create an initial migration.
cp myapp/models.py.orig myapp/models.py
../manage.py makemigrations myapp
../manage.py migrate
manage.py migrate returns the following:
....
Running migrations:
Applying myapp.0001_initial... FAKED
Then I swap in the new models and generate a new migration.
cp myapp/models.py.new myapp/models.py
../manage.py makemigrations myapp
The result of makemigrations is in myapp/migrations/0002_notificationlog.py:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='NotificationLog',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('tstamp', models.DateTimeField(help_text=b'Log time', auto_now_add=True)),
('recipient', models.CharField(max_length=100)),
('subject', models.TextField()),
],
options={
},
bases=(models.Model,),
),
]
Run this migration:
../manage.py migrate
manage.py migrate acts like everything is OK:
....
Running migrations:
Applying myapp.0002_notificationlog... OK
I can see the log entries appear in django_migrations, but the table is not created.
I'm lost. Any idea what to try next?
Update
When running migrate -v 3 as requested, I see
Running pre-migrate handlers for application auth
followed by a similar line for each installed app.
Then
Loading 'initial_data' fixtures...
Checking '/var/www/environment/default/myproj/myproj' for fixtures...
No fixture 'initial_data' in '/var/www/environment/default/myproj/myproj'.
repeated a total of 13 times, the number of unmanaged apps.
Then
Running migrations:
Applying myapp.0001_initial... FAKED
followed by
Running post-migrate handlers for application auth
with a similar line for each installed app.
For migration 0002, the output is the same, except for
Running migrations:
Applying myapp.0002_notificationlog... OK
Note also that sqlmigrate doesn't output anything either:
../manage.py sqlmigrate myapp 0002 -v 3
Produces nothing at all.
Update 2
I copied myapp into a new project and was able to run migrations on it, but migrations stopped working when I imported my main project settings. Are there settings I should be aware of that could affect migration execution, particularly if I've been using South with previous versions of Django?
The problem disappeared with generic project settings and reappeared with my old, complex project settings. I tracked the problem down to a database Router class that was missing an allow_migrate method.
DATABASE_ROUTERS = [ 'myproj.routers.DatabaseAppsRouter', ]
I use this router to handle queries for a separate app in the project (readonly/MySQL).
Sadly I can't blame anyone but myself, since the Django documentation states clearly:
Note that migrations will just silently not perform any operations on a model for which [allow_migrate] returns False. (link)
I had created this router some time ago and didn't add the allow_migrate method to my router class when I upgraded to Django 1.7. When I added the method and made sure it returned True when needed, migrations run and the problem is solved.