Re-init migrations in South with Django [duplicate] - python

I've accumulated quite a few migrations using South (0.7) and Django (1.1.2) which are starting to consume quite a bit of time in my unit tests. I would like to reset the baseline and start a fresh set of migrations. I've reviewed the South documentation, done the usual Google/Stackoverflow searching (e.g. "django south (reset OR delete OR remove) migration history") and haven't found anything obvious.
One approach I've contemplated would involve "starting over" by "removing" South or "clearing" the history manually (e.g. clear the db table, remove migration files from the migrations director) and just re-run,
./manage.py schemamigration southtut --initial
So, if anyone has done this before and has some tips/suggestions they would be greatly appreciated.

If you need to selectively (for just one app) reset migrations that are taking too long, this worked for me.
rm <app-dir>/migrations/*
python manage.py schemamigration <app-name> --initial
python manage.py migrate <app-name> 0001 --fake --delete-ghost-migrations
Don't forget to manually restore any dependencies on other apps by adding lines like depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial")) to your <app-dir>/migrations/0001_initial.py file, as the first attribute in your migration class just below class Migration(SchemaMigration):.
You can then ./manage.py migrate <app-name> --fake --delete-ghost-migrations on other environments, per this SO answer. Of course if you fake the delete or fake the migrate zero you'll need to manually delete any left-over db tables with a migration like this.
A more nuclear option is to ./manage.py migrate --fake --delete-ghost-migrations on the live deployment server followed by a [my]sqldump. Then pipe that dump into [my]sql on the environments where you need the migrated, fully-populated db. South sacrilege, I know, but worked for me.

EDIT - I'm putting a comment below at the top of this as it's important to read it before the > accepted answer that follows #andybak
#Dominique: Your advice regarding manage.py reset south is dangerous
and may destroy the database if there are any third party apps using
south in the project, as pointed out by #thnee below. Since your
answer has so many upvotes I'd really appreciate it if you could edit
it and add at least a warning about this, or (even better) change it
to reflect #hobs approach (which is just as convenient, but doesn't
affect other apps) - thanks! – chrisv Mar 26 '13 at 9:09
Accepted answer follows below:
First, an answer by the South author:
As long as you take care to do it on all deployments simultaneously, there shouldn't be any problem with this. Personally, I'd do:
rm -r appname/migrations/
./manage.py reset south
./manage.py convert_to_south appname
(Notice that the “reset south” part clears migration records for ALL apps, so make sure you either run the other two lines for all apps or delete selectively).
The convert_to_south call at the end makes a new migration and fake-applies it (since your database already has the corresponding tables). There's no need to drop all the app tables during the process.
Here's what I'm doing on my dev + production server when I need to get rid of all these unneeded dev migrations:
Make sure we have the same DB schema on both sides
delete every migrations folder on both sides
run ./manage.py reset south (as the post says) on both sides = clears the south table *
run ./manage.py convert_to_south on both sides (faking 0001 migration)
then I can re-start to make migrations and push the migrations folders on my server
* except if you want to clean only one app among others, if so you'll need to edit your south_history table and delete only the entries about your app.

Thanks to the answers by Dominique Guardiola and hobs, it helped me solve a hard problem.
However there are a couple of issues with the solution, here is my take on it.
Using manage.py reset south is not a good idea if you have any third party apps that uses South, for example django-cms (basically everything uses South).
reset south will delete all migration history for all apps that you have installed.
Now consider that you upgrade to the latest version of django-cms, it will contain new migrations like 0009_do_something.py. South will surely be confused when you try to run that migration without having 0001 through 0008 in the migration history.
It is much better/safer to selectively reset only the apps that you are maintaining.
First of all, make sure that your apps don't have any desync between migrations on disk, and migrations that have been executed on the database. Otherwise there will be headache.
1. Delete migration history for my apps
sql> delete from south_migrationhistory where app_name = 'my_app';
2. Delete migrations for my apps
$ rm -rf my_app/migrations/
3. Create new initial migrations for my apps
$ ./manage.py schemamigration --initial my_app
4. Fake execute the initial migrations for my apps
This inserts the migrations into south_migrationhistory without touching actual tables:
$ ./manage.py migrate --fake my_app
Step 3 and 4 is actually just a longer variant of manage.py convert_to_south my_app, but I prefer that extra control, in such delicate situation as modifying the production database.

Like thnee (see her answer), we're using a gentler approach to the South author's (Andrew Godwin) suggestion quoted elsewhere here, and we're separating what we do with the code base from what we do to the database, during deployment, because we need the deployments to be repeatable:
What we do in the code:
# Remove all the migrations from the app
$ rm -fR appname/migrations
# Make the first migration (don't touch the database)
$ ./manage.py schemamigration appname --initial
What we do to the database once that code is deployed
# Fake the migration history, wiping out the rest
$ ./manage.py migrate appname --fake --delete-ghost-migrations

If you are just working on the dev machine, I wrote a management command that does pretty much what Dominique suggested.
http://balzerg.blogspot.co.il/2012/09/django-app-reset-with-south.html
In contrast of the south author suggestion, this will NOT HARM other installed apps using south.

Following is only if you want to reset all apps. Please backup your all databases prior to that work. Also note down your depends_on in initial files if there are any.
For once:
(1) find . -type d -name migrations -exec git rm -rf '{}' \;
(2) find . -type d -name migrations -exec rm -rf '{}' \;
(3) ./manage.py schemamigration <APP_NAME> --initial
(4) [GIT COMMIT]
Test bootstrapping your project before push. Then, for each local/remote machine, apply following:
(5) [GIT PULL]
(6) ./manage.py reset south
(7) ./manage.py migrate --fake
Do initial (3) for each app you want to re-involve. Note that, reset (6) will delete only migration history, therefore not harmful to libraries. Fake migrations (7) will put back migration history of any 3rd party apps installed.

delete necessary file from app folder
instance path
cd /usr/local/lib/python2.7/dist-packages/wiki/south_migrations
wiki -is my app

Related

Relation does not exist error in Django

I know there are many questions about this problem, I looked through the solutions and unfortunately none of them worked for me.
I created a new app called "usermanagement", and added a model to the app. After adding the model I added usermanagement to INSTALLED_APPS in settings. Then I ran python manage.py makemigrations, and python manage.py migrate. This all worked fine! I also did try running the migrations with the app-name.
The problems start when I try to add a new instance of the model to the database in the Python-Django shell, by using:
>>>a = ClubOfficial(name="randomName", email="randomemail#random.com")
>>>a.save()
I get the following error:
django.db.utils.ProgrammingError: relation
"usermanagement_clubofficial" does not exist
LINE 1: INSERT INTO "usermanagement_clubofficial" ("name", "email") ...
Below is the model code:
class ClubOfficial(models.Model):
name = models.CharField(max_length=254)
email = models.EmailField(max_length=254)
If it helps, I use postgresql, and have tried restarting the server. The other apps in the program also work perfectly fine, it is just usermanagemenet that has this problem.
Does anyone know what could be going wrong?
Thank you for your time!
Note: I created a new app now with a different name, copy-pasted things from usermanagement and everything worked fine. I think the problem might be that before there was an app named usermanagement which was deleted, before I created it again. Maybe that messed up the database somehow.
TL;DR: Make sure your app's migrations folder has an __init__.py file. If it isn't there, create it again as an empty file.
I ran into this. In my case I had a previously working django app, not yet moved to production, so I deleted everything in my app's migrations folder, then using django extensions I wiped the postgresql database and cached files with:
./manage.py clear_cache
./manage.py clean_pyc
./manage.py reset_schema
./manage.py reset_db
# then deleted all files (including __init__.py) from my app's migrations folder.
I verified that my postgresql database had no tables. I then ran:
./manage.py makemigrations
./manage.py migrate
Which gave the output:
No changes detected
./manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
(about 11 more lines of output here which are similar)
It is notable that my model's names where nowhere in the migration. I printed the tables in my postgresql database and the Widget and Section tables were both missing. Running the app gave me this error (I substituted 'app' and 'model' for their real names):
ProgrammingError at /my_path
relation "app_model" does not exist
LINE 1: ..."."my_field", "app_model"."my_field" FROM "appname...
So the tables for the models were not being created in the database. My app's migrations folder was also completely empty. The solution was to just add an empty __init__.py to my app's migrations folder, and after that running makemigrations was able to create and save the migration file in the folder. This could then be executed with migrate. You can test this for yourself by running makemigrations with and without the __init__.py in the migrations/ folder.
This solution was not mine but one given by user Ljubitel on another post but it was not the accepted answer there, but the accepted answer didn't work for me so I wrote this solution here to hopefully help others.
I had this same problem, but all I had to do was run
$ python manage.py makemigrations
and
$ python manage.py migrate
In case you have deleted your migration folder.
Create a folder called migration in whatever app name you have created and then create a file in the migration folder called __init__.py
In my case I was pointing to a different databases between my local server and the production server. The database that the production server was pointing to was a few versions behind, so the server could not locate the relation. If your issue were localized to one environment, check the configs first.
Another method to fix relation does not exist error
Create same table in db(postgre, mysql) using sql query tool
now comment your model in models.py and admin.py
run migration using :
python manage.py makemigrations app_name
python manage.py migrate
now uncomment and run migrations command again
I encountered same issue and fixed using following method, I am using postgres(pgadmin 4).

Best way to add Django migrations to a django project

I have a Django application initially created for version 1.6 and I've just finished the upgrade for the last version. All the models has managed = False and prior none of them was managed by south and now I want to start using Django migrations for 1.7 version.
Which would be the best and seamless way to do it? I'm afraid that just changing managed = True in all models and run manage.py makemigrations will make a mess in both migrations files and database.
Thanks
EDIT
As was suggested I ran manage.py makemigrations. It created the script 0001_initial with some model definitions but not for all the objects in models package. It creates 11 tables but I have 19 tables. All models has managed = True and I don't have any database router.
Most depends by the code
The project does not have migrations at all
./manage.py makemigrations
./manage.py migrate
The project has South migrations:
you can:
move the south migrations in south_migrations
or
totally remove the south migrations
and
./manage.py makemigrations
./manage.py migrate
if you go for option 1 you have to remember to keep uptodate your migrations with both systems (south and django). This is useful only if you want to keep django <1.7 compatibility
You have a pluggable application
This is the most complex situataion as you must preserve the south compatibility and you have to manage different version of south. Here the how to:
move the south migrations in south_migrations
run ./manage.py makemigrations
to prevent South to load the wrong migratins put the following code into migration.__init__.py
```
"""
Django migrations
This package does not contain South migrations. South migrations can be found
in the ``south_migrations`` package.
"""
SOUTH_ERROR_MESSAGE = """\n
For South support, customize the SOUTH_MIGRATION_MODULES setting like so:
SOUTH_MIGRATION_MODULES = {
'wfp_auth': 'wfp_auth.south_migrations',
}
"""
# Ensure the user is not using Django 1.6 or below with South
try:
from django.db import migrations # noqa
except ImportError:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured(SOUTH_ERROR_MESSAGE)
```
I have done the migration from 1.6 to 1.7 on an existing project. It was fairly painless.
I renamed my old South migrations folders and let the django 1.7 migrations create a new one. (i.e. $mv appname/migrations appname/migrations.south) That will make it easier to go back to South for any reason and will keep from having a jumbled mess of both in your migrations folders.

Django : Table doesn't exist

I dropped some table related to an app. and again tried the syncdb command
python manage.py syncdb
It shows error like
django.db.utils.ProgrammingError: (1146, "Table 'someapp.feed' doesn't exist")
models.py
class feed(models.Model):
user = models.ForeignKey(User,null=True,blank=True)
feed_text = models.CharField(max_length=2000)
date = models.CharField(max_length=30)
upvote = models.IntegerField(default=0)
downvote = models.IntegerField(default=0)
def __str__(self):
return feed.content
What I can do to get the tables for that app ?
drop tables (you already did),
comment-out the model in model.py,
and ..
if django version >= 1.7:
python manage.py makemigrations
python manage.py migrate --fake
else
python manage.py schemamigration someapp --auto
python manage.py migrate someapp --fake
comment-in your model in models.py
go to step 3. BUT this time without --fake
For those that may still be having trouble (like me), try this out:
Comment out all the URL's in the main app's urls.py
Then go ahead and run migrations:
$ ./manage.py makemigrations
$ ./manage.py migrate
The problem was alleviated by removing the ()'s
solved_time = models.DateTimeField('solved time', default=timezone.now())
to
solved_time = models.DateTimeField('solved time', default=timezone.now)
I got this answer from reddit
What solved my problem in situation when manage.py setmigration and then migrate to the SQL database is not working properly did is following:
Run command : python manage.py migrate --fake MyApp zero
After that: python manage.py migrate MyApp
And the problem that rises with connections.py and and after running correctly the migration command is solved! At least for me.
I'm using Python (3.x), MySQL DB, Django (3.x), and I was in situation when I needed after some time of successfully creating tables in my database, that some error regarding connections.py raises. But, above commands helped. I hope they will help all those who are having these type of problems.
I just ran migrations with the name of the app attached, for all the apps I had provisioned and that worked.
e.g. python3 manage.py makemigrations my_custom_app
After running for all of them I ran a migrate command to seal the deal.
python3 manage.py migrate. That was it. I'm still wondering why django behaves this way sometimes though.
none of the above solutions worked for me, I finally solved by
sudo systemctl stop mysql.service
sudo apt-get purge mysql-server
sudo apt-get install mysql-server
sudo systemctl stop mysql.service
In my case the code that I pulled had managed = False and I wanted the tables to be maintained by Django.
But when I did makemigrations the custom tables were not being detected or I was getting the error that the app_name.Table_name does not exist
I tried the following:
delete all the migration files inside the migrations folder (except init.py file) and then makemigrations then finally migrate
above 2 answers
this
PS: This solution is only feasible if backup is present or data is not important or you are just started creating the tables, as purging mysql will lead to loss of data
This is linked to the migration data in the scripts inside the project not matching with the migration scripts in the database as far as I could tell.
I solved this by the following steps :
Delete all the migration scripts under migration folder except __ini__
Make sure that the model.py contains the same structure as the table in the database and managed=True
Remove all Django Created tables like auth_user,... etc
Run the following code
$ ./manage.py makemigrations
$ ./manage.py migrate
This will create the migration scripts again and will apply it to your database.
I had this issue where I was playing with same database structure in production vs development. While dropping and recreating tables will probably resolve the issue, its worth checking your database itself and see if the model is actually correct. For myself I created the development database incorrectly with the table names all in lowercase while in production the first letter of tables were capitalized. I used the python manage.py inspectdb command on production db, and compared it to the model and realized that in the model it was trying to insert data to table 'test' instead of 'Test' for example. Hope that helps some of you in future.
I had a similar issue.
I had another python (with a class) file which need access to DB.
For some reasons, when running 'makemigrations' this file was processed (I guess this is linked to some import chains).
In this class, I had a method containing a default arg method(defaultModel=Model.get_default()) in the signature which was accessing to the default object in the DB (static method included in the Model class).
A the import time, this default arg was evaluated and as the table is not populated yet, it gives this error.
So I just set None for the default args and asks for the default model object inside the method. This solved the issue.
I have to face same issue and there are a couple of approaches, but the one I think is the most probable one.
Maybe you are loading views or queries to database but you haven´t granted enough time for Django to migrate the models to DB. That's why the "table doesn't exist".
Make sure you use this sort of initialization in you view's code:
Class RegisterForm(forms.Form):
def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
A second approach is you clean previous migrations, delete the database and start over the migration process.
I tried all of the above tricks and never worked for me.
I commented on all imports and URLs that called a particular Table
In this solution, your data will be removed. I removed the app and created the app again. I copied the app folder somewhere and delete the app folder from my project. I commented on all lines in urls.py and files similar views.py and admin.py that use this app. also app name in settings.py.
In mysql:
truncate django_migrations;
truncate django_admin_log;
Do this for all models in your app and change n.
n is app id.
delete from auth_permission where content_type_id=n
delete from django_content_type where app_label='appname'
python manage.py startapp your_app_name
Then uncomment previous lines and restore files and run
python manage.py makemigrations
python manage.pt migrate
I faced the same problem, some of the above mentioned answers seemed not to work for me, but here's a simple 4 step solution:
1) Delete the migrations files below __init__.py (don't delete __init__.py) in your specific app.
2) python manage.py makemigrations AppName
3) python manage.py migrate --fake AppName zero
4) python manage.py migrate AppName
Hope these works for you.
I faced the same issue earlier when I accidentally deleted my migrations folder in an app. I was able to fix it by running manual makemigrations for that specific app.
Here's the fix for Windows,
py manage.py makemigrations <your_app_name>
py manage.py migrate
For other OS you need to replace py with python3 or python
I hope this helped fix your issue!
if the python manage.py migrate still doesn't work I mean when you do this it nothing do anything you can delete the app's migrations from django_migrations table after then do
python manage.py migrate

Django South - Migration not re-creating model after dropping table from sqlite3

I am a newbie and a new user to Django and South. I created a new model (approval.py) in my models package (and linked it in model's init.py) and was able to successfully migrate my app to accept the new model. However, when I tried looking for that model on the admin site, I was getting a 403 forbidden error since the Guardian permissions were not applied.
So I directly dropped the table from sqlite command prompt and tried to perform the following commands again:
$python manage.py syncdb
...
(use ./manage.py migrate to migrate these)
$python manage.py schemamigration myapp --auto
Nothing seems to have changed.
$python manage.py migrate myapp
Running migrations for myapp:
- Nothing to migrate.
- Loading initial data for myapp.
Installed 0 object(s) from 0 fixture(s)
However, the table is no longer getting created, when I check in sqlite command prompt. Also, I had registered this model on my admin.sites.url, but it is no longer displaying it and giving error as:
DatabaseError at /admin/myapp/approval/
no such table: myapp_approval
Request Method: GET
Request URL: http://localhost/admin/approval/
Django Version: 1.5.1
Exception Type: DatabaseError
Exception Value:
no such table: myapp_approval
Exception Location: /home/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py in execute, line 362
Python Executable: /home/bin/python2.7
Python Version: 2.7.5
Python Path:
['.........']
Server time: Wed, 9 Jul 2014 19:12:00 -0500
I have already checked all the other questions posted on StackOverflow about using South for migrations, in particular the error about "Nothing seems to have changed". However I am not able to resolve my issue with any of those solutions.
I kindly request some help in either :
Creating the approval model again from scratch and migrating it successfully
Or Repairing the existing approval model.
Thanks.
Finally after a lot of trial and error, something very simple worked for me. I did not have much luck with the south migrations. So as I had manually dropped the table from sqlite3, I decided to manually create the table in sqlite3 and everything worked perfectly fine.
I used the below script on the sqlite3 prompt and it solved my issue and I was able to access the approval page correctly through my admin site and perform all CRUD operations on it.
CREATE TABLE "myapp_approval" ("id" integer NOT NULL PRIMARY KEY, "desc" varchar(256) NOT NULL);
Thanks everyone for your help and support!
You have already created a migration that creates the new table, and according to South's history management, you've run this migration. South does not know about the actual changes to your database.
What you need to do is to revert to a migration before the new table was created. If you look in your apps folder, you'll find a migrations folder with some migration files in it. If you created the new table in e.g. migration 0005, you need to (optionally) migrate backwards to 0005, and then you need to fake a backwards migration to 0004 and migrate again:
manage.py migrate myapp 0005
manage.py migrate myapp 0004 --fake
manage.py migrate myapp

Issues with creating table via migration

I have created a model and when I try to create the table via migration using python manage.py migrate app_name and in response I get
- Nothing to migrate.
- Loading initial data for app_name.
Installed 3 object(s) from 1 fixture(s)
But the table is not created , its a simple process but I don't know why the table is not created. The db used is postgresql and I have also used syncdb but doesn't work .
It seems you haven't created any migrations. You need to create them, before they can be run.
For app's initial first migration you run:
./manage.py schemamigration your_app --initial
For following migrations you run (provided you want to create an automatic migration):
./manage.py schemamigration your_app --auto
You can see more examples in the tutorial.

Categories