Django makemigrations wants to delete everything it just created - django

I just followed this procedure:
makemigrations (success)
migrate (success)
Copy the app on another server (with the migration files)
Create a new empty database on that server
migrate (success, it creates the correct schema)
Fill the new database with data
Just to test: migrate ....
At this point Django says I have "changes that are not yet reflected in a migration, and so won't be applied. Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them"
But when I run makemigrations, it creates a new one that wants to "Remove field" every foreign key and "Delete model" all of my models. If I run it it empties my database. My models.py are intact.
What is happening ??

I had the same problem in my project. Running forward I can say that django removes models that has no import (making the Delete model migration). The documentation says that you should import your model in the myApp/models/__init__.py file (see https://docs.djangoproject.com/en/1.11/topics/db/models/#organizing-models-in-a-package).
In my case I imported the model somewhere to make manipulations but model had been removing elsewhere.
I had made a useless import in an admin.py file that has solved my situation (I didn't try to follow the documentation and import it in the __init__.py but sure it should help).
I had not realized yet why does it work that way (hope that someone could note this moment) and also hope this solution will help you.

I've just had the same errors, but I hit the makemigrations building a migration full of Remove Field and Delete Model commands before I tried the migrate command.
In my case, the solution was related this being an old project I was resurrecting, and it had a number of Model.Meta.app_name values set, as well as entries in apps.py for each project. These were now in conflict with the way settings was interpreting the project, and even though my models were imported into views and admin, they weren't being seen by the migration code. Deleting these app_name tags on the models, and modifying the AppConfig name in apps.py solved this, so that the running makemigrations again caused the expected changes (alter field, etc), and all was fine.
I didn't find any other questions or answers that quite matched this one and my experience, so I hope if anyone else looks for this, they'll find it here like I did ;-)

Related

Deleted all my migrations including __init.py__

I am a beginner using Django. I have recently been working on a website that has a few different pages. I reference a couple of views from other apps in urls.py. One app I used to take inputs and make some calculations, so it had some forms defined. It was all working fine and I was able to import the views fine, but I changed one of my form field names. This caused some problems because I was storing these values in a database. That made sense to me because I had already saved some data with the previous naming convention and now I had changed it. So, I figured that deleting my database and migrations would allow me to start over and start a new database with my updated fields. I messed up though because I read that I should not have deleted my init.py file in my migrations folder.
I have tried re-doing my migrations with makemigrations and migrate but I keep getting an error saying that no changes are made and no new migrations show up in my folder. Also, now when I look in my urls.py file, the imported views and apps are showing up with a red underline and says "import package".
I have also tried reverting my code back and was able to get the migration files back, but the same error was shown in my urls.py file.
I have tried just about everything I could find online, but am now thinking that I may just have to recreate these apps.
Any help is appreciated!
First of all, to rename a form field, just change it in the models and then make and apply migrations. Django should detect the renaming of an existing field and create migrations.AlterField(...) statements (you can inspect the migration files that were created, and freely delete them if they are not yet applied/migrated).
First, please check if adding the empty file called __init__.py to the migration folder solves the problem. This is a python requirement, to let the interpreter know that the folder contains a python module.
Also if you have downloaded the project from somewhere, you need to have the existing migrations. Deleting them and recreating them yourself will likely fail.
After that just try running
python manage.py makemigrations
python manage.py migrate
If there are still no changes, check if there are migrations applied to your database by looking at the django_migrations table or by running this command:
python manage.py showmigrations
If this did not help, try to start with a clean project:
Backup all your code changes and revert to the starting point, the __init__.py file should be back and you should also delete the database (db.sqlite3)
run the migrate command
add all your code changes
check if your code changes have new migration files, they could cause problems. If you have not created or modified them manually, you can delete and let Django recreate them

Django migrations : relation already exists

I have trouble with django model migrations.
I have some models in my app, and I already have some data inside.
When I added some models in my application, and I run makemigrations, the app report that there is no change.
I know that sometimes some errors came when migrate, so I delete django_migrations table in my database and run makemigrations again, and now program found my new fields.
The problem now is that if I run migrate system tell me that some tables already exist. (Which is ok and correct, because they do). I don't want to delete those tables, because I have data already inside.
I can't run migrate --fake, because program will think that I already have all the tables, which is not true.
So, I am looking for a way to tell the program : run migration, if table exist skip it. (--fake it)
Another question is why is this happening to me, that makemigrations don't recognise my changes (some cache problems,...)?
How about doing this way ?
python manage.py makemigrations
(Skip this step if you have already have migration file ready)
It will create migrations for that package lets say with a name like 0001_initial.py
Edit the file manually so that you delete all models there except that was already created in database.
Now you do a fake migration. This will sync your database with models.
python manage.py migrate --fake
Then run makemigrations again to have rest of the tables created along with a new migration file.
python manage.py makemigrations
Regarding your other question, Why makemigrations didn't recogonize your models can be because of reasons like:
Migrations for those changes are already there in some migration file.
You missed it to mention package_name in INSTALLED_APPS but i believe you did it here.
every time you make changes to your models, try these steps :
python manage.py makemigrations [your app name]
then:
python manage.py migrate
it should work fine. but remember if you have already data(rows) in your tables you should specify the default value for each one the queries.
if not, Django prompt you to specify the default value for them
or you can just try to use blank=True or null=True in your fields like below :
website = models.URLField(blank=True)
the possible cause or this is that you have another migration in the same folder starts with the same prefix... maybe you make another migration on the same table on another branch or commit so it's saved to the db with the same prefix ie: 00010_migration_from_commit_#10, 00010_migration_from_commit_#11
the solution for this is to rename the migration file like this 00011_migration_from_commit_#11
I tried to edit the related migration file and commented the part where it creates that specific column, then ran python manage.py migrate
The main problem is the existing tables that are disabling the migration of the new tables, so the solution is straight-forward:
** Try to add managed = False to the existing dB so it won't be detected by migrate
** Redo it for all existing old tables :
class Meta:
managed=False
It sometimes gets boring when we have a lot of tables in the same application but it works perfectly!

Django makemigrations No changes detected in app

I have trouble with my makemigrations command.
Note: I have successfully make migrations till now, so it is not the first time I try to make migrations on this project.
I have my project in INSTALLED_APPS.
Problem: For some reason project stop detecting any changes in my models.
Inside my project models.py I have:
from myproject.myfolder import myModel1
from myproject.myfolder import myModel2
from myproject.myfolder import myModel3
if a add new models as myModel4 class and import it inside models.py and I try to
python mamange.py makemigrations environment=local
I get No changes detected
I know there are a lot of posts of making the initial migrations, so I even try
python manage.py makemigrations myproject environment=local
I even try to delete all files in __pycache__ but it doesn't work for me.
I even try to delete database and create new one, and it doesn't work either.
EDIT:
Because I delete the database and make it new again, database is empty, but I still get same message.
I just ran into an issue like this. In my case, the problem was that I had installed, through pip, the stable version of the package that I was developing, and Django was importing the stable version rather than my development version. To check if this is the case with you, try adding a syntax error to models.py. If makemigrations doesn't trigger the syntax error, then you'll know that your version is not even being loaded by the python interpreter.
If your model is not inheriting from django model then, you will see aforementioned error. Make sure that your custom model inherits from django models.Model, something like this.
from django.db import models
class Posts(models.Model):
...
Deleting the DB and creating new one will never work since it refer the previous migration files. Delete all previous migration files and pycache files except init. Then try running these.
python manage.py migrate --fake-initial
python manage.py makemigrations
python manage.py migrate
This worked for me

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

south migration error app "is not available in this migration"

This problem is basically the same as the previous question
here.
However, the answer there does not work for me. I've installed the trunk version of south, manually entered the import line in the migration file in question, and done a full 'startmigration' in a separate directory and examined the 0001_initial.py file.
I have a Django project with several applications in it, one of them (named 'core') being referred to by the others. The south migration is trying to create a new table, with a column that has a foreign key to a model in core.
I'm currently importing core in the migration in question (0006), and I even added it to migration 0001, although it doesn't seem like that should matter.
Before I do something drastic, like removing that field, running the migration, and adding the field manually, is there a known manual workaround for fixing this south issue?
You probably did not use the --freeze option like this:
python manage.py startmigration <appname> migrate_core --freeze core
Having created a migration like so:
./manage.py startmygration appname --model NewModel
This error occurs:
"The model 'program' from the app 'core' is not available in this migration."
Recreating the migration like this fixes it:
./managepy startmigration appname --model NewModel --freeze core.Program
Just doing "--freeze core" did not do the trick for me.
You can receive this error by trying to access a class that resides in another django app. Check to make sure the class you are trying to access is in the models dictionary.