Django migrate fails when creating new table - django

We are fairly new to Django. We we have an app and a model. We'd like to add an 'Category' object to our model. We did that, and then ran 'python manage.py makemigrations'.
We then deploy our code to a server running the older code, and run 'python manage.py migrate'. This throws 2 pages of exceptions, finishing with 'django.db.utils.ProgrammingError: (1146, "Table 'reporting.contact_category' doesn't exist")'
This seems to be looking at our models.py. If we comment out Category from our model, and all references to it, the migration succeeds.
I thought that the point of migrations is to make the database match what the model expects, but this seems to require that the model match the database before the migration.
We clearly are doing something wrong, but what?

I believe you skipped some migration in the server, so now you are missing some tables (I have been in that situation. Ensure migrations directories are on your .gitignore. You CAN NOT check in migrations files, you have to run makemigrations on the server). This can be solved by tracing back up to the point the database and models files match, but it is a risky process if it is your production database, so you should make a full backup before proceeding, and try the process on a different computer before.
This would be my advice:
Delete migration files from the server.
Comment the models that rise the error.
Set the server's migration history to the point the
database is, using python manage.py makemigrations and python manage.py migrate --fake-initial (this will update the migration files without actually attempting to modify the database).
Uncomment the models that raise the error.
Run python manage.py makemigrations and python manage.py migrate.
If, after you comment the models that raise the exception, you get a different exception, you have to keep on commenting and attempting again. Once a migrations succeeds, you can uncomment all commented models and make an actual migration.

Remember to run python manage.py makemigrations if you made changes to the models.py then run python manage.py makemigrations
Both commands must be run on the same server with the same database

Related

relation "django_admin_log" already exists

when i try to run python manage.py migrate i run into following error
Upon running python manage.py run migrations it says no changes detected. and when i runserver it gives me warning that i have unapplied migrations as well.i have been searching internet for two hours but got not solution. Someone knowing the solution please share :)
The table in your database that stores migration data to keep track of what has been applied is out of date. Try running python manage.py migrate --fake
Try python manage.py makemigrations [app name] and if still, this does detect changes then delete the folder named migrations which is inside your application folder and then use this python manage.py makemigrations [app name]. Once migration happens successfully do the python manage.py migrate.
Don't Try This at Home
I faced this issue, i make two changes,
change AUTH_USER_MODEL, so i have one migraiton about it
second one add new field for my folder_model(migration name: folder_model 0021)
When my first migrate attempt(I already run makemigrations commands on local so i have migration files), it says;
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency account.0001_initial on database 'default'
This error reiases because i change the AUTH_USER_MODEL in the middle of the project, normally you have to remove your database and fresh start from the beginnig(also truncate migrations etc.), according to Django doc -> https://code.djangoproject.com/ticket/25313
To fix this issue, you don't have to delete all migrations on db, just delete the migrations about admin(not from project just database)
After that just run
python manage.py migrate
It throws relation "django_admin_log" already exists. For this issue, run:
python manage.py migrate --fake
That's it, but not completely. Make fake migration act like you already make your all migrations successfully and save these on db. The issue came here that i have another migration about folder_model 0021 and with fake migration it doesn't applied to my database table but saved to db_migrations table.
So fix this issue, delete the folder_model 0021to database migration table (just 0021 not all folder_model migrations).
After delete just run python manage.py migrate
Everything is fine!

Django manage.py: Migration applied before its dependency

When running python manage.py migrate I encounter this error:
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration
<appname>.0016_auto_<date2>_<time2> is applied before its dependency
<appname>.0001_squashed_0015_auto_<date1>_<time1>
running showmigrations returns:
<appname>
[X] 0001_squashed_0015_auto_<date1>_<time1> (15 squashed migrations)
[X] 0016_auto_<date2>_<time2>
[ ] 0017_<modelname>_squashed_0019_auto_<date3>_<time3> (3 squashed migrations)
I was trying out django-extensions yesterday, when it all got messed up after me running some direct SQL queries and I reset hard using git. I'm still learning about migrations, so I don't understand what is wrong, since it seems to me that both migrations already have been applied.
Thank you for your help!
This worked for me. I thank my coworker for sharing this knowledge after I searched online for many hours.
Start your db shell
python manage.py dbshell
Use the database you want. If you don't know, run .databases (SQLite) or SHOW databases
mysql>use <database_name>;
Retrieve all the migrations under your app
mysql> select * from django_migrations where app='<app>';
You will see the output with ids next to all migrations. Look at the migration you want to drop. Say the id is 361
mysql> delete from django_migrations where id=361;
You have squashed the migrations, so one of the dependencies that 0016_auto_<date2>_<time2> had is now part of the newly created squashed migrations. Meanwhile the 0016_auto_<date2>_<time2> has already been run and now you're trying to run the squashed migration.
I personally don't know if there's any way to fix this automatically. You will need to fix the issues yourself. If you have version control, revert these changes and try to rethink how you should squash the migration without affecting old ones.
I have solved this problem when i did (custom user model) by this steps:
delete this file :
migrations\0001_initial.py
delete this :
db.sqlite3
put this code in settings.py :
AUTH_USER_MODEL = 'users.CustomUser'
Then do (makemigrations) then (migrate )
run server .. the problem solved :)
i have used this link it is help me to solve the problem of dependency :
https://docs.djangoproject.com/en/3.1/topics/auth/customizing/
Due to limitations of Django’s dynamic dependency feature for swappable models, the model referenced by AUTH_USER_MODEL must be created in the first migration of its app (usually called 0001_initial); otherwise, you’ll have dependency issues.
In addition, you may run into a CircularDependencyError when running your migrations as Django won’t be able to automatically break the dependency loop due to the dynamic dependency. If you see this error, you should break the loop by moving the models depended on by your user model into a second migration. (You can try making two normal models that have a ForeignKey to each other and seeing how makemigrations resolves that circular dependency if you want to see how it’s usually done.)
run this python manage.py dbshell
INSERT INTO public.django_migrations(app, name, applied)
VALUES ('YOUR_APP_NAME, '0017_<modelname>_squashed_0019_auto_<date3>_<time3>', now());
and you should be fine. If Your migration was changing a lot to the database, then I am afraid it won't be that easy to fix it.
you need to fake migrations and migrate again
just make sure that you have a backup from your data because when you migrate again you need to delete apps table.
make sure that you look at show migrations and migrate un migrated apps by its sequence
Edit the dependencies of the conflicting migration, so that it no longer references the already applied migration.
Then run python manage.py migrate again and it should be fixed.
Warning: this only work suppossing that the state of the database matchs the state you get having applied the conflicting migration.
I had the same issue on 2020 with Django 3.0.6.
I tried all the relevant answers with no success. So I went in my database and deleted all the tables. You must export the relevant tables if you have done lot of work. I mainly delete django files in my database. And after, run:
python manage.py makemigrations <my-app>
And:
python manage.py migrate
Export your relevant tables if any.
First back up your database before resolving the conflicts, (Use "python manage.py dumpdata > db.json" for SQLite).
Execute python manage.py dbshell, to access the database.
Delete the migrations rows that are having conflicts from the django_migrations table.
Rename the tables conflicting in the database
Execute the makemigrations and migrate commands
After successful migrations, Drop the newly readded tables and finally restore the previously renamed tables to match the migrations need
I had the same problem, and here's how I solved it.
The following is my error message
File "/usr/local/lib/python3.11/site-packages/django/db/migrations/loader.py", line 327, in check_consistent_history
raise InconsistentMigrationHistory(
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration aaaa.0024_campaign_template is applied before its dependency bbbb.0005_templatemodel_from_template on database 'default'.
My solution
python manage.py migrate bbbb
python manage.py migrate
Because I changed the Django's app name in batches, the application order was not consistent when applied to the database. The bbbb that aaaa relies on was not created first, so I manually created the bbbb first
Migration file is not created for all app:
step 1:
create migration folder and add __init__.py file for all app
step 2:
delete db.sqlite3 database
step 3:
python manage.py migrate
python manage.py makemigrations
Delete all of your migrations folder
Delete the database(sqlite3)
Then run the makemigrations and migrate command
Delete the migration files.
Run:
python manage.py migrate
python manage.py makemigrations
python manage.py migrate
python manage.pyrunserver

makemigrations doesn't detect changes in model

I'm using django 1.9.6. I recently deleted my migrations and ran migrate --run-syncdb and makemigrations my_app. Today I added a new field to one of my models:
models.py:
value = models.PositiveSmallIntegerField(null=True)
I tried to migrate the changes, but makemigrations doesn't detect the change. It's just the development version, so I can resync (I don't have to preserve the data), but running --run-syncdb again doesn't detect it either.
Why isn't this migrating?
Delete every past migration files and __pycache__ files except __init__
then:
python manage.py makemigrations yourApp
After that make sure that the db is the same as the code in model.py (remove new changes) and run next line:
python manage.py migrate --fake-initial
Now add all your changes in the model.py and run next lines:
python manage.py makemigrations
python manage.py migrate
Best Regards,
Kristian
I had the same issue. I realised I had a property defined on the model with the same name as a field I was trying to add on the model. Ensure the model doesn't have a model property/method with the same name as the field you are trying to add.
You should not delete migrations, you should squash them. If you simply deleted the files you likely messed things up, the easiest way to recover is re-sync your code to get the files back. A more complex route is to delete all the records from the django_migrations table and re-init the migrations from scratch but there is more steps/issues than I can really get into and I don't recommend it.
The reason makemigrations is not detecting the change is likely because there is no migrations folder in that app. If you run python manage.py makemigrations your_app --initial it might detect and generate the migrations or it might freak out because of the difference in your files and the django_migrations table.
The --run-syncdb command is great when you don't care about the data, usually before you actually deploy but once you start using migrations you should not use the --run-syncdb command anymore. For instance, during initial development here is the code I run every model change instead of dealing with migrations:
dropdb mydb && createdb mydb && python manage.py migrate --run-syncdb && python manage.py loaddata initial
I store all the initial data in a fixtures file and the command wipes out the entire database, the --run-syncdb rebuilds the schema, and the initial data is loaded while skipping actual migration files.
So, if you don't care about any of your data or can easily move it to a fixture than you can drop and re-create the DB. You are then free to delete all migration folders and you can use the command above until you go live and need to move to using migrations.
*** UPDATE FOR DJANGO 1.11 *** STILL USING ON 3.2.5 ***
I started using Django 1.11 and noticed the test framework can fail if you have dependencies on framework models and don't actually have migrations. This is the new command i'm using to wipe everything out and start over while still developing.
set -e
dropdb yourdb
createdb yourdb
find . -name "migrations" -type d -prune -exec rm -rf {} \;
python manage.py makemigrations name every app you use seperated by space
python manage.py migrate
python manage.py loaddata initial
I put this in a builddb.sh at the root of my project (next to manage.py) so I can just run ./builddb.sh. Be sure to delete it on deploy so there is no accidents!
Try creating a migrations folder that contains an empty __init__.py file inside your app folder if there is no migrations folder already. And make migrations.
In my case, I created a new project and created an app. The python manage.py makemigrations returned no change detected although I had added a handful of models.
Found out that you need to manually add the name of your app in the INSTALLED_APPS list inside your settings.py file. Unless you do that, no change in the migration of that app can be detected.
If you're deleting a model, and expecting the changes to be picked up in migrations, ensure that the model doesn't have a *.pyc still lying around.
Another case is abstract classes. Make sure that your model’s metaclass does not have the abstract = True property.

django - schema migration - how to add a field

I have a django 1.8 app working with a db.
I'm trying to change the schema of a table using the built-in migration.
Here are the steps I did:
In my dev invironment, I grabbed the app source and ran
python manage.py sycdb
then I ran
python manage.py loaddata ~/my_data.json
then I modified modes.py. Added a field and renamed a field...all from the same table 'TABLE1' which had no data.
then
python manage.py makemigrations myapp
python manage.py migrate
Error: django.db.utils.OperationalError: table "myapp_someother_table" already exists
then ran
python manage.py migrate --fake-initial
worked!
but when I browsed to the admin page for TABLE1, I get this error:
OperationalError: no such column: myapp_table1.my_new_field_id
I checked the db and yes, there is no such column.
How can I procceed from here? I prefer to fix this via django.
If I fix it straight in the db, then the migration goes out of sync.
Migrations do not automagically see that you have made changes. Migrations detect changes by comparing the current model with the historical model saved in the migration files.
In this case, you didn't have any historical models, since you didn't have any migrations. Django was not able to detect any changes in your models, even though they were different from your database.
The correct way to make changes to your model is to first run manage.py makemigration <my_app>, and then make the changes to your model, followed by another manage.py makemigrations.
You might not be able to do it via pure django and keep your data. I don't have personal experience with south but there are a lot of mentions if this tool. Just in case if nothing else works for you...
Here is what I did to make things work, but there must be a better way so please add more answers/comments...
I deleted the sqlite db and the migration folder
I made the desired changes to model.py
ran syncdb
ran loaddata to load the json data dump that I had saved previously.
just started the dev server

Django 1.8: Create initial migrations for existing schema

I started a django 1.8 project, which uses the migrations system.
Somehow along the way things got messy, so I erased the migrations folders and table from the DB, and now I'm trying to reconstruct them, with no success.
I have three apps (3 models.py files), and the models reflect the tables EXACTLY!
The best approach that I've found so far was:
Erase all migrations folders. Done!
Delete everything from the django_migrations table. Done!
Run python manage.py makemigrations --empty <app> for every app. Done!
Run python manage.py migrate --fake. Done! (although it works only if I run it after every makemigrations command.
Now I add a new field, run the makemigrations command, and I receive the following error:
django.db.utils.OperationalError: (1054, "Unknown column 'accounts_plan.max_item_size' in 'field list'")
I've been burning HOURS on this thing. How the h**l can I initialize the migrations so I can continue working without migration interruptions every time?
Why is it so complicated? Why isn't there a simple one-liner: initiate_migrations_from_schema?
EDIT:
Now things get even nastier. I truncated the django_migrations table and deleted all the migrations folder.
Now I try to run python manage.py migrate --fake-initial (something I found in the DEV docs), just so it sets up all of Django's 'internal' apps (auth, session, etc) and I'm getting:
(1054, "Unknown column 'name' in 'django_content_type'").
Now, this "column" is not a real column. It's a #property defined in Django's contenttypes app. WHAT IS GOING ON HERE? Why is it identifying the name property as a real column?
Finally got it to work, although I don't know why and I hope it will work in the future.
After doing numerous trials and going through Django's dev site (link).
Here are the steps (for whoever runs into this problem):
Empty the django_migrations table: delete from django_migrations;
For every app, delete its migrations folder: rm -rf <app>/migrations/
Reset the migrations for the "built-in" apps: python manage.py migrate --fake
For each app run: python manage.py makemigrations <app>. Take care of dependencies (models with ForeignKey's should run after their parent model).
Finally: python manage.py migrate --fake-initial
After that I ran the last command without the --fake-initial flag, just to make sure.
Now everything works and I can use the migrations system normally.
I'm sure I'm not the only one who encounters this issue. It must be documented better and even simplified.
Update for Django 1.9 users:
I had this scenario again with a Django 1.9.4, and step 5 failed.
All I had to do is replace --fake-initial with --fake to make it work.
django ..., 1.8, 1.9, ...
What you want to achieve is squashing existing migrations and use replacement for them.
How to do it right without using any command when releasing (a case without impact on database and coworkers).
For every app, get rid of its migrations folder:
mv <app>/migrations/ <app>/migrationsOLD/
For each that app run: python manage.py makemigrations <app>.
Customize each new migration:
if you have a complex app, or more apps and related models between them, to avoid CircularDependencyError or ValueError: Unhandled pending operations for models:
prepare second empty migration in <app> 0002_initial2.py (put there dependency to app_other::0001_initial.py and <app>::0001_initial.py as well - all ForeignKey, M2M related to models created in 0001 migration step in other apps)
All must be in order - sometimes it will require more migrations to prepare. Take care of dependencies attribute here in each Migration.
take care of initial values - verify yourself all RunPython actions from migrationsOLD and copy the code to new initial migration if needed.
(optional for --fake-initial) Add initial=True to all new Migration classes (0002 too if was added).
Add replaces attribute in new Migration class. (like own custom a squashmigrations). Put there all old migrations from <app>
Verify everything with makemigrations.
assert "No changes detected"
Check if migrate -l show [x] everywhere
assert similar:
[X] 0001_initial
[X] 0002_initial2 (102 squashed migrations)
Example:
For old:
0001_initial.py
0002_auto.py
...
0103_auto.py
prepare:
0001_initial.py
0002_initial2.py (optional but sometimes required to satisfy dependency)
and add to replacesto last one (0002 here, can be 0001):
replaces = [(b'<app>', '0002_auto.py'), ..., (b'<app>', '0103_auto.py')]
0001_initial.py should be named the same way as old one.
0002_initial2.py is new one, but it's a replacement for old migrations so Django will treat it as loaded.
I've run into this scenario but I've never had to drop the database to solve it. Typically I delete the migrations folder from the app's, and remove the migration entries from the database.
I would try to run make migrations one app at a time. If any of the app's rely upon other tables obviously add them last.
Also I usually just run, python manage.py makemigrations then just python manage.py migrate Even with the initial migration it should work fine with Django 1.7 and 1.8.
If you are using routers, might be a problem there. Check method allow_migrate if it is executed in a right way in routers.py. Try to set return value always to be True, and check whether it resolves problem,
def allow_migrate(self, db, app_label, model_name=None, **hints):
return True