Django 1.8: Create initial migrations for existing schema - django

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

Related

Django - wont let me add a new field to my model because 1054, "Unknown column 'field list'")

I am trying to simply add a boolean field to a model in my database following the simple rules:
- add field to model
- python manage.py makemigrations app
- python manage.py migrate app
Works all but 99% of the time. So during the second step (makemigrations), with my newly added field in my model raring to go, i get an error:
django.db.utils.OperationalError: (1054, "Unknown column 'model.field' in 'field list'")
Excellent. its not letting me make migrations by adding a new field..... because it cant find the field that I am trying to newly add... makes perfect sense!
Anyway, I have gone as far as deleting all my migrations, removing my new field, making migrations again, migrating... all fine - so now i have only 1 migration file (0001)...
Follow the same steps as above... ERROR
Am i missing something ridiculous here? I mean, adding a field to a model is very simple, and I have done it probably 1000 times. Why does Django tease me so
EDIT: Answer:
OK I have done it.
After deleting the migrations file, truncating the migrations table and migrating with 0001_initial.py, I made an empty migrations file (python manage.py makemigrations --empty app) and added the field in manually.... then I migrated and it worked! Baffled at this to be honest, but at least the change has been made:
Delete all migration files
Truncate the django_migrations table
comment the new boolean field
run python manage.py makemigrations
run python manage.py migrate --fake
run python manage.py makemigrations --empty app
add field in manually to the empty migrations file in the operations:
migrations.AddField('modelName', 'fieldName', models.BooleanField(default=False)),
run python manage.py migrate
uncomment the new boolean field so it represents what you made in the migrations operations
Disclaimer- Follow this only on local system, for production do understand the steps and then execute.
Kindly follow these steps:
Delete all migration files
Truncate the django_migrations table
comment the new boolean field
run python manage.py makemigrations
run python manage.py migrate --fake
Uncomment the boolean field
run python manage.py makemigrations
run python manage.py migrate
Generally these steps solve any kind of migration problem
An another reason can be if you are using django_rest_framework then the serialiser too needs to be updated as per your model change.
This is an issue that has persisted with me and lead me down a lot of rabbit holes dropping tables etc. A simple solution I have found is answering "N" when django asks you if you are renaming a field of that model (when running makemigrations). What that then essentially performs is a deletion of your previous field and creates the new field. Be careful as you may lose data on existing field so this works with fields which are either new or relatively easy to 'refill' their data required. You may need to run --fake if you get an error with regards to not being able to 'drop field' when migrating after makemigrations. If you would like to go back to your migration state before the problem you may need to delete the migrations you have done since then and try the above solution.
Update:
I did the above for a Boolean field and my data was kept. Even though I said N, it seems as if it is essentially a renaming.
Another source of the problem: I have a ModelForm based on the model. The ModelForm definition defines two extra fields. I had to comment out those two fields from the Form definition before doing the migration steps. Once the migration was done, I un-commented the two fields.

Django Programming error column does not exist even after running migrations

I run python manage.py makemigrations and I get:
No changes detected
Then, python manage.py migrate and I get:
No migrations to apply.
Then, I try to push the changes to production:
git push heroku master
Everything up-to-date
Then, in production, I repeat the command:
heroku run python manage.py migrate
No migrations to apply.
Just in case, I run makemigrations in production:
heroku run python manage.py makemigrations
No changes detected
WHY then I get a
ProgrammingError at ....
column .... does not exist
"No changes detected" means the database is coherent with the code.
How can I debug this?¡?
I got the same problem (column not exist) but when I try to run migrate not with makemigrations (it is the same issue I believe)
Cause: I removed the migration files and replaced them with single pretending intial migration file 0001 before running the migration for the last change
Solution:
Drop tables involved in that migration of that app (consider a backup workaround if any)
Delete the rows responsible of the migration of that app from the table django_migrations in which migrations are recorded, This is how Django knows which migrations have been applied and which still need to be applied.
And here is how solve this problem:
log in as postgres user (my user is called posgres):
sudo -i -u postgres
Open an sql terminal and connect to your database:
psql -d database_name
List your table and spot the tables related to that app:
\dt
Drop them (consider drop order with relations):
DROP TABLE tablename ;
List migration record, you will see migrations applied classified like so:
id | app | name | applied
--+------+--------+---------+
SELECT * FROM django_migrations;
Delete rows of migrations of that app (you can delete by id or by app, with app don't forget 'quotes'):
DELETE FROM django_migrations WHERE app='yourapp';
log out and run your migrations merely (maybe run makemigrations in your case):
python manage.py migrate --settings=your.settings.module_if_any
Note: it is possible that in your case will not have to drop all the tables of that app and not all the migrations, just the ones of the models causing the problem.
I wish this can help.
Django migrations are recorded in your database under the 'django_migrations' table. This is how Django knows which migrations have been applied and which still need to be applied.
Have a look at django_migrations table in your DB. It may be that something went wrong when your migration was applied. So, delete the row in the table which has the migration file name that is related to that column that 'does not exist'. Then, try to re-run a migration.
Here's what i tried and it worked:
Go and add manually the column to your table
run python manage.py makemigrations
go back drop that column you added
run python manage.py migrate
I had a similar issue - the error message appeared when I clicked on the model on the django-admin site. I solved it by commenting out the field in models.py, then running migrations. Following this I uncommented the field and re ran the migrations. After that the error message disappeared.
My case might be a bit obscure, but if it helps someone, it is worth documenting here.
I was calling a function in one of my migrations, which imported a Model of said migration regularly, i.e.
from myApp.models import ModelX
The only way models should be imported in migrations would be using e.g. RunPython:
def myFunc(apps, schema_editor):
MyModel = apps.get_model('myApp 'MyModel')
and then calling that function like so:
class Migration(migrations.Migration):
operations = [
migrations.RunPython(initialize_mhs, reverse_code=migrations.RunPython.noop),
]
Additionally the original import worked until I modified the model in a later migration, making this error harder to locate.
So, I always run into this sort of problem, so today I decided to try and work it out at the database level. Thing is, I changed a model field name which Django didn't bother reflecting in a migration file. I only found out later when I ran into problems. I later looked at the migration files and discovered there was no migration for that change. But I didn't notice because I made other changes as well, so once I saw a migration file I was happy.
My advice. Create migration for each change one at a time. That way you get to see if it happened or not.
So here's my working through it in MySQL.
open mysql console.
show databases; # see all my dbs. I deleted a few
drop database <db-name>; # if needed
use <db-name>; # the database name for your django project
show tables; # see all tables in the database
DESCRIBE <table-name>; # shows columns in the database
SHOW COLUMNS FROM <db-name>; # same thing as above
ALTER TABLE <table-name> CHANGE <old-column-name> <new-column-name> <col-type>; # now I manually updated my column name
If you're using postgresql, just google the corresponding commands.
The issue was in the Models for me, for some reason Django was adding '_id' to the end of my Foreign Key column. I had to explicitly set the related named to the Foreign Key. Here 'Cards' is the parent table and 'Prices' is the child table.
class Cards(models.Model):
unique_id = models.CharField(primary_key=True, max_length=45)
name = models.CharField(max_length=225)
class Prices(models.Model):
unique_id = models.ForeignKey(Cards, models.DO_NOTHING)
Works after changing to:
class Cards(models.Model):
unique_id = models.CharField(primary_key=True, max_length=45)
name = models.CharField(max_length=225)
class Prices(models.Model):
unique_id = models.ForeignKey(Cards, models.DO_NOTHING, db_column='unique_id')
When I get this error, my extreme way to solve it is to reset my database:
Reset your database
For Postgresql on Heroku:
Heroku > your_app > Resources > database > add-ons > click on your database and open it
For postgresql
settings > Reset database
Delete all files in your_app > migrations > __pycache__ except __init.py__
Delete all files in your_app > migrations except __pycache__ folder and __init.py__
Then run:
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
type in to create your superuser, then run:
python manage.py makemigrations
python manage.py migrate
python manage.py
If you are able to inspect your models from your admin section, then it should be all okay now.
Just remove corresponding row migrations for that model in 'django_migrations' model in database.
And re run python manage.py migrate app_name
I tried all these answers with not much luck! What I did to have this problem solved with no harm was to go back through the migration files and find where the actual model was being created for the first time then manually add the field (in the column not being existed error message). Until if you run makemigrations --dry-run you get/see "No changes detected" and that worked. Basically, in my case, I had to carefully take my desired db changes back in time in proper migration file, rather creating a new migration now at the end of migration dependency chain.
Open the latest py file created after running the makemigrations command inside migrations folder of that particular app.
Inside class Migration there is a list attribute called 'operations'.
Remove the particular elements migrations.RemoveField(...).
Save and run python manage.py migrate.
A easier solution to the problem is to make your models exactly like it is in the migration first. and run python manage.py migrate.
Then revert those changes
Run
python manage.py makemigrations
python manage.py migrate
To check for which migrations are applied and which are not, use -:
python manage.py showmigrations
I solved a similar problem by deleting all migrations files (Don't forget to make a backup) and python manage.py makemigrations all of them into one clean file in development and pulling new files on the server. Before then I had dropped existing tables on the PostgreSQL.
I was getting this error for some reason when Django was looking for a column of type ForeignKey named category_id when the actual name in the database was category. I tried every Django solution I could imagine (renaming field, explicitly setting column name, etc.). I didn't want to drop tables or rows as this was a production database. The solution was simply to rename the column manually using SQL. In my case:
ALTER TABLE table_name
RENAME COLUMN category TO category_id;
Make sure you backup your database, ensure this won't break any other applications consuming that particular table, and consider having a fallback column if necessary.
What helped me in the end was simply dropping the database and creating it again as well as deleting all migrations files (including cache). (only removing migrations file didn't work for me at all)
sudo su - postgres
psql
DROP DATABASE 'yourdatabase';
CREATE DATABASE 'yourdatabase';
GRANT ALL PRIVILEGES ON DATABASE 'yourdatabase' to 'yourdjangouser';
then just
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
If you're in development and you make some examples of data that's not important, this step is beneficial for me: just flush your data, make migrations, and migrate:
python manage.py flush
python manage.py makemigrations
python manage.py migrate
After that, you may create a new database from scratch, I hope this information was helpful.
Solved this issue by running
python manage.py migrate
in Heroku Bash shell

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

Django Migration is not applying the migration changes

Using django 1.7.7 I want to use django's migration to add or remove a field.
so I modified model.py and ran
python manage.py makemigrations myproj
Migrations for 'myproj':
0001_initial.py:
- Create model Interp
- Create model InterpVersion
python manage.py migrate myproj
Operations to perform:
Apply all migrations: myproj
Running migrations:
Applying myproj.0001_initial... FAKED
python manage.py runserver
Then checked the admin page, it is not updated.
Then I tried removing the migration folder and tried again; the migrate command says there are no migrations to apply.
How can I do the migration?
Note: I want to use the new technique using django's migration not the old south approach.
Make sure that the migrations/ folder contains a __init__.py file
Lost half an hour over that.
Deleting the migration directory is never a good idea, because Django then loses track of which migration has been applied and which not (and once an app is deployed somewhere it can become quite difficult to get things back in sync).
Disclaimer: whenever things like that occur it is best to backup the database if it contains anything valuable. If in early development it is not necessary, but once things on the backend get out of sync there is a chance of things getting worse. :-)
To recover, you could try resetting your models to match exactly what they were before you have added/removed the fields. Then you can run
$ python manage.py makemigrations myproj
which will lead to an initial migration (0001_initial...). Then you can tell Django to fake that migration, which means to tell it to set its internal counter to this 0001_initial:
With Django 1.7:
$ python manage.py migrate myproj
With Django >= 1.8:
$ python manage.py migrate myproj --fake-initial
Now, try to change your model and run makemigrations again. It should now create a 0002_foobar migration that you could run as expected.
In my case, the migrations were not being reflected in mysql database. I manually removed the row of 'myapp'(in your case 'myproj') from the table 'django_migrations' in mysql database and ran the same commands again for migration.
Most of the above solutions would help in the issue, however, I wanted to point out another possible (albeit rare) possibility that the allow_migrate method of database router may be returning False when it should have returned None.
Django has a setting DATABASE_ROUTERS which will be used to determine which database to use when performing a database query.
From the docs:
if you want to implement more interesting database allocation behaviors, you can define and install your own database routers.
A database router class implements up to four methods:
db_for_read(model, **hints)
db_for_write(model, **hints)
allow_relation(obj1, obj2, **hints)
allow_migrate(db, app_label, model_name=None, **hints)
From the documentation:
allow_migrate(db, app_label, model_name=None, **hints)
Determine if the migration operation is allowed to run on the database with alias db. Return True if the operation should run, False if it shouldn’t run, or None if the router has no opinion.
It is possible that one of the database routers in sequence is returning False for the migration that you're trying to run, in which case the particular operation will not be run.
I find Django migrations a bit of a mystery, and tend to prefer external tools (liquibase, for example).
However, I just ran into this "No migrations to apply" problem as well. I also tried removing the migrations folder, which doesn't help.
If you've already removed the migrations folder, here's an approach that worked for me.
First, generate the new "clean" migrations:
$ python manage.py makemigrations foo
Migrations for 'foo':
dashboard/foo/migrations/0001_initial.py
- Create model Foo
- Create model Bar
Then look at the SQL and see if it looks reasonable:
$ python manage.py sqlmigrate foo 0001
BEGIN;
--
-- Create model Foo
--
CREATE TABLE "foo" ("id" serial NOT NULL PRIMARY KEY, ... "created_at" timestamp with time zone NOT NULL, "updated_at" timestamp with time zone NOT NULL);
CREATE INDEX "..." ON "foo" (...);
COMMIT;
Then apply execute that same SQL on your database.
I'm using Postgres but it will be similar for other engines.
One way is to write the content to a file:
$ python manage.py sqlmigrate foo 0001 > foo.sql
$ psql dbname username < foo.sql
BEGIN
CREATE TABLE
CREATE INDEX
COMMIT
Another is pipe the SQL directly:
$ python manage.py sqlmigrate foo 0001 | psql dbname username
Or copy and paste it, etc.
pip install django-extensions
and add this in the install app of settings.py
INSTALLED_APPS = [
'django_extensions'
]
Then run
python ./manage.py reset_db
Then run migrations again
python manage.py makemigrations
python manage.py migrate
Now, run migrations for your installed apps
python manage.py makemigrations your_app_name
python manage.py migrtate your_app_name
Done! See Your Database...
In addition to the other answers, make sure that in models.py, you have managed = True in each table's meta
You can remove your db
python manage.py makemigrations
python manage.py migrate
python manage.py migrate --run-syncdb
and see your data base this is working :)
Similar to Andrew E above but with a few changes especially where you haven't deleted the migrations folder in your quest to resolve the issue
1 - In your intact migration folder just examine the 000*.py files counting from the highest down to initial.py till you find the one where your Model is defined, say 0002_entry.py
2 - python manage.py sqlmigrate app-name 0002 > 0002_sql.txt to capture the SQL commands
3 - Edit this file to ensure there are no hard CR/LFs and the ALTER, CREATE INDEX commands are each on own single line
4 - Log into your DB (I have Postgres) and run these commands
In Database delete row myproj from the table django_migrations.
Delete all migration files in the migrations folder.
Then run python manage.py makemigrations and python manage.py migrate commands.

Django South - table already exists

I am trying to get started with South. I had an existing database and I added South (syncdb, schemamigration --initial).
Then, I updated models.py to add a field and ran ./manage.py schemamigration myapp --auto. It seemed to find the field and said I could apply this with ./manage.py migrate myapp. But, doing that gave the error:
django.db.utils.DatabaseError: table "myapp_tablename" already exists
tablename is the first table listed in models.py.
I am running Django 1.2, South 0.7
since you already have the tables created in the database, you just need to run the initial migration as fake
./manage.py migrate myapp --fake
make sure that the schema of models is same as schema of tables in database.
Although the table "myapp_tablename" already exists error stop raising
after I did ./manage.py migrate myapp --fake, the DatabaseError shows
no such column: myapp_mymodel.added_field.
Got exactly the same problem!
1.Firstly check the migration number which is causing this. Lets assume it is: 0010.
2.You need to:
./manage.py schemamigration myapp --add-field MyModel.added_field
./manage.py migrate myapp
if there is more than one field missing you have to repeat it for each field.
3.Now you land with a bunch of new migrations so remove their files from myapp/migrations (0011 and further if you needed to add multiple fields).
4.Run this:
./manage.py migrate myapp 0010
Now try ./manage.py migrate myapp
If it doesn't fail you're ready. Just doublecheck if any field's aren't missing.
EDIT:
This problem can also occur when you have a production database for which you install South and the first, initial migration created in other enviorment duplicates what you already have in your db. The solution is much easier here:
Fake the first migration:
./manage migrate myapp 0001 --fake
Roll with the rest of migrations:
./manage migrate myapp
When I ran into this error, it had a different cause.
In my case South had somehow left in my DB a temporary empty table, which is used in _remake_table(). Probably I had aborted a migration in a way I shouldn't have. In any case, each subsequent new migration, when it called _remake_table(), was throwing the error sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists, because it did already exist and wasn't supposed to be there.
The _south_new bit looked odd to me, so I browsed my DB, saw the table _south_new_myapp_mymodel, scratched my head, looked at South's source, decided it was junk, dropped the table, and all was well.
If you have problems with your models not matching your database, like #pielgrzym, and you want to automatically migrate the database to match the latest models.py file (and erase any data that won't be recreated by fixtures during migrate):
manage.py schemamigration myapp --initial
manage.py migrate myapp --fake
manage.py migrate myapp zero
manage.py migrate myapp
This will only delete and recreate database tables that exist in your latest models.py file, so you may have garbage tables in your database from previous syncdbs or migrates. To get rid of those, precede all these migrations with:
manage.py sqlclear myapp | manage.py sqlshell
And if that still leaves some CRUFT lying around in your database then you'll have to do an inspectdb and create the models.py file from that (for the tables and app that you want to clear) before doing the sqlclear and then restore your original models.py before creating the --initial migration and migrating to it. All this to avoid messing around with the particular flavor of SQL that your database needs.
Perform these steps in order may help you:
1) python manage.py schemamigration apps.appname --initial
Above step creates migration folder as default.
2) python manage.py migrate apps.appname --fake
generates a fake migration.
3) python manage.py schemamigration apps.appname --auto
Then you can add fields as you wish and perform the above command.
4) python manage.py migrate apps.appname
If you have an existing database and app you can use the south conversion command
./manage.py convert_to_south myapp
This has to be applied before you do any changes to what is already in the database.
The convert_to_south command only works entirely on the first machine you run it on. Once you’ve committed the initial migrations it made into your VCS, you’ll have to run ./manage.py migrate myapp 0001 --fake on every machine that has a copy of the codebase (make sure they were up-to-date with models and schema first).
ref: http://south.readthedocs.org/en/latest/convertinganapp.html
As temporary solution, you can comment the Table creation in the migration script.
class Migration(migrations.Migration):
dependencies = [
(...)
]
operations = [
#migrations.CreateModel(
# name='TABLE',
# fields=[
# ....
# ....
# ],
#),
....
....
Or
If the existing table contains no rows (empty), then consider deleting the table like below. (This fix is recommended only if the table contains no rows). Also make sure this operation before the createModel operation.
class Migration(migrations.Migration):
dependencies = [
(...),
]
operations = [
migrations.RunSQL("DROP TABLE myapp_tablename;")
]
One more solution(maybe a temporary solution).
$ python manage.py sqlmigrate APP_NAME MIGRATION_NAME
eg.,.
$ python manage.py sqlmigrate users 0029_auto_20170310_1117
This will list all the migrations in raw sql queries. You can pick the queries which you want to run avoiding the part which creates the existing table