I have changed the Django models, and I use the Django schemamigration to update the database. But, when I do python manager.py migrate app, it throws this error message:
_mysql_exceptions.OperationalError: (1050, "Table 'forum_user' already exists")
Then the table that django south is trying to create already exists and doesn't match the state of your database.
If this is the first time you're migrating, remember that before you make schemamigration changes, you must set the initial state via schemamigration myapp --initial and migrate app --fake to match the database to the south database state.
manage.py convert_to_south myapp also does the above as a convenience method.
To start using south...
Make sure your django tables match your current database tables exactly - if you planned to add or remove columns, comment those out.
Run python manage.py schemamigration myapp --initial
Run python manage.py migrate myapp --fake
Make changes to your django model
Run python manage.py schemamigration myapp --auto
Run python manage.py migrate myapp
Update
Note django 1.7+ ships with migrations and south is no longer in use.
There are only two commands worth noting..
manage.py makemigrations (handles --initial)
manage.py migrate
Written by the same author as South, crowd funded. Go django.
I just fixed a duplicate table issue locally and wanted to document my workflow to help others.
The key to success was creating an --empty migration before the new models are added. The flow:
Merged in another persons work that excluded info on a model I have locally.
normal schemamigration --auto was adding a table/model again and caused "already exists error".
Solved by commenting out the new model and running an empty migration via clear; python manage.py schemamigration --empty APPNAME MIGRATION_FILE_NAME. This creates a "declaration" of the state of the models with no forward/backwards commands. Be 100% sure the current state of models (python files) and database are in sync!!! This most current migration will be used for the creation of a differential to migrate correctly (next).
uncomment the new model and run clear; python manage.py schemamigration APPNAME --auto to create the true and desired differential off (uses the --empty migration just created). The new migration will have forward/backward commands that should be appropriate for your new model. Review...
finish off with clear; python manage.py migrate
The lesson learned is that --auto looks at the last APP+migration file to create a forward/backwards diff. If the last migration does NOT have in the dictionary a model you have in DB it will be created again causing an "already exists" error. Think of the dictionary as a contract between Django and the DB stating "here's what everything should look like". The migration can include commands that create duplicate tables and will only be exposed during ```migrate`` command.
The above info should fix the problem. Presented in part to help people and also for review in case I am doing something foolish.
Related
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!
I switched database names, and now my Django models are out of sync with my database tables. What is the command to force Django to perform all migrations to sync up the models and the tables? I don't want manage.py migrate --fake.
I fixed this by manually deleting all the migrations and running makemigrations again to get a new initial migration file. Then, I went into my database and manually dropped all the tables that Django created in the app. Finally, I deleted all of the rows in the table django.migrations that included the app name. After all that, I ran manage.py migrate and the database was in sync.
When you change something in your models you must execute:
python manage.py makemigrations
for creation new changed schema of your models. Then:
python manage.py migrate <app_name>
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.
So I am a newbie to Django and I had added a field to a model.py and that created issues in Django.
I learned I needed a migration tool, and used south. Turns out south has issues with sqlite. So I configured Django settings for MYSQL. I can add data to the DB (MYSQL)
I deleted the db.sqlite3 file , but it comes back after ever syncdb.
When I run syncdb it says:
Syncing...
Creating tables ...
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
Synced:
> django.contrib.admin
> django.contrib.auth
> django.contrib.contenttypes
> django.contrib.sessions
> django.contrib.messages
> django.contrib.staticfiles
> south
Not synced (use migrations):
- accounts
(use ./manage.py migrate to migrate these)
So my questions are:
1. Changing to MYSQL did not remove the mid migration that south failed on, as I hoped it would. What are my options now in order to deal with this
Do I even have to do anything, or can I keep working on my app or is this mid migration something to address? I ask because the new MYSQL DB seems to have the new field I added, which was why I wanted to migrate in the first place. So you can see my confusion...my migration broke, but now with MYSQL, the fields are fine, but Django still thinks im in the middle of a migration. Why is this and what is the recommendations?
thanks
I have fought many many many (many) times with Databases & Migrations & South... I hope this information helps you to fix your issues and save you some hours of hard work
Migrating accounts app
I have a question here, is accounts the name of your app ? Or is it an external app ?
The accounts app seems to be managed by South, that means that It won't be synced with the command python manage.py syncdb, you will need to migrate it by yourself with:
# This command generates the migrations file
python manage.py shchemamigration accounts --initial
# This command use the migrations file and apply the changes to the DB
python manage.py migrate accounts
# --initial is used only in the INITIAL migration
# If you modify the models on the accounts app and want to migrate again
# You will need to
python manage.py shchemamigration accounts --auto
python manage.py migrate accounts
Keep an eye on your migrations
If you check the folder migrations following the standard structure it is yourapp/yourapp/migrations
If you delete your database, remember to delete your migrations files, is better to start over unless you need to save the Database changes
Make sure that your Database and your migrations are synchronized, if they are synchronized add some changes to the database will be easy
Some times, although you're using south, when you do python manage.py syncdb your app will be synced, I will explain which problems can come from here:
Your app models are created in the database with the command python manage.py syncdb
After 1. you do python manage.py schemamigration --initial and it will create the initial migrations
Now, if you try to do python manage.py migrate yourapp it will fail because the tables has already been created, so you need to fake the initial migration with:
python manage.py migrate yourapp --fake
and from here you could use south without problems
How to "restart" the database
This process will empty the database and delete all the migrations, take care if you have some data you want to save
Sometimes you will mess with the migrations, and depending on the issue, it can be faster to drop the database and start the migrations again:
python manage.py dbshell
# Next 3 lines inside the MySQL console
>> drop database yourappdatabase
>> create database yourappdatabase
>> quit
# Delete all the migrations within the migrations folder
rm yourapp/yourapp/migrations/00*
python manage.py syncdb
python manage.py schemamigration yourapp --initial
python manage.py migrate yourapp
How to save informations from the database
Some times when you're starting a new app you will delete/create the database many times, and to avoid typing again and again data on the models, it could be useful to create migrations from some models with:
python manage.py dumpdata yourapp.ModelName > file.json
To reload this data again you just need to:
python manage.py loaddata file.json
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