9π
My improved soultion:
To create the table south_migrationhistory
in the other database:
./manage.py syncdb --database="my_db_name_for_apps"
You can now use a standard :
./manage.py migrate my_app
Here is my actual db_router.py
# -*- coding: UTF-8 -*-
apps =['app1', 'app2' ]
db_name = 'my_db_name_for_apps'
class sh_router(object):
"""A router to control all database operations on models from applications in apps"""
def db_for_read(self, model, **hints):
"""Point all operations on apps models to db_name"""
if model._meta.app_label in apps :
return db_name
return None
def db_for_write(self, model, **hints):
"""Point all operations on apps models to db_name"""
if model._meta.app_label in apps:
return db_name
return None
def allow_relation(self, obj1, obj2, **hints):
"""Allow any relation if a model in apps is involved"""
if obj1._meta.app_label in apps or obj2._meta.app_label in apps:
return True
return None
def allow_syncdb(self, db, model):
"""Make sure the apps only appears on the db_name db"""
if model._meta.app_label in ['south']:
return True
if db == db_name:
return model._meta.app_label in apps
elif model._meta.app_label in apps:
return False
return None
9π
I found all the answers to be somewhat inaccurate, therefore, here is a summary.
First of all, everybody should of course read the very few lines about multiple databases in the South documentation π
The way to do this is to manually edit migration files to point to the correct database. The easiest way is to add this to the top of all files:
from south.db import dbs
db = dbs['name_of_you_nondefault_db']
The basic reason is that South does not pick up the name of the database from your database routers. This feature is simply not implemented and probably never will be with the coming of Django 1.7.
But to get things started, run:
python manage.py syncdb
Now, you have the south_migrationhistory table. Then to migrate your special database, do:
python manage.py migrate
The south_migrationhistory will NOT be created in every database, only the default one. So migration history can be kept centralized.
Multiple databases with different copies of the same application
In case you have multiple databases that you need to migrate the same application inside, you should not use a singular migration history.
Instead, create the south_migrationhistory like so:
python manage.py sql south | PGOPTIONS="-c search_path=NAME_OF_YOUR_SCHEMA_TO_CREATE_IN" python manage.py dbshell --database=name_of_you_nondefault_db
Now, you should run your migration specifying BOTH the app_label and the database to get the south_migrationhistory from.
python manage.py migrate name_of_app --database=name_of_you_nondefault_db
- [Django]-Cancel saving model when using pre_save in django
- [Django]-Django queryset attach or annotate related object field
- [Django]-Adding a Log entry for an action by a user in a Django App
5π
In my db_router.py
file I just uncomment the 'south'
app in my apps list.
I launch a syncdb
to create the table south_migrationhistory
in the otherdb
database.
./manage.py syncdb --database="otherdb"
And next comment again the 'south'
app in my apps list.
You can now use a standard
./manage.py migrate my_app --database="otherdb"
Here is my db_router.py
#-*- coding: UTF-8 -*-
apps =['app1',
'app2',
'south', # <<<---------------- Comment / Uncomment here
]
db_name = 'otherdb'
class sh_router(object):
"""A router to control all database operations on models from applications in apps"""
def db_for_read(self, model, **hints):
"""Point all operations on apps models to db_name"""
if model._meta.app_label in apps :
return db_name
return None
def db_for_write(self, model, **hints):
"""Point all operations on apps models to db_name"""
if model._meta.app_label in apps:
return db_name
return None
def allow_relation(self, obj1, obj2, **hints):
"""Allow any relation if a model in apps is involved"""
if obj1._meta.app_label in apps or obj2._meta.app_label in apps:
return True
return None
def allow_syncdb(self, db, model):
"""Make sure the apps only appears on the db_name db"""
if db == db_name:
return model._meta.app_label in apps
elif model._meta.app_label in apps:
return False
return None
- [Django]-How to make the foreign key field optional in Django model?
- [Django]-Django: Arbitrary number of unnamed urls.py parameters
- [Django]-What are the benefits of pip and virtualenv?
1π
As Tomasz said, you have to syncdb your βgisβ db too in order to create all the required tables, including south_migrationhistory.
./manage.py syncdb --database=gis
- [Django]-How do I refresh the values on an object in Django?
- [Django]-What is the purpose of apps.py in Django 1.9?
- [Django]-Django CharField with no max length
1π
Seems like Django 1.7 has allow_migrate() in its database router class to address this.
For earlier Djangos:
- you need south_migrationhistory in any db where you want migrations
- do a regular
syncdb
to put all the regular auth_* etc. tables in thedefault
db - that will put south_migrationhistory in
default
- donβt do
syncdb --database=other
, that will duplicate all the auth_* etc.
tables inother
-
instead, copy the
south_migrationhistory
table fromdefault
toother
, e.g.sqlite3 main.sqlite ".sc south_migrationhistory" | sqlite3 other.sqlite
or equivalent pg_dump command or whatever
-
then use
migrate --database=other
At least this gets everything in the right place until you migrate to 1.7 π
- [Django]-Celery and transaction.atomic
- [Django]-ValueError: Cannot add *: instance is on database "default", value is on database "None"
- [Django]-Is there a way to auto-increment a Django field with respect to a foreign key?
0π
I know the thread is old but I had the same problem and Google got me that thread.
So first you need to change the way you do your datamigration:
def forwards(self, orm):
"Write your forwards methods here."
obj = orm.Obj()
obj.name = 'my name'
obj.save(using=db.db_alias)
The variable db.db_alias contain the name of the db to be used, so you will need to do everything with βusginβ and use db.db_alias as the db name.
then you run your migration with
./mange migrate App βdatabase=DB_NAME
in case of schemamigration just directly use db.function like south does.
- [Django]-How to delete project in django
- [Django]-Django and SSL question
- [Django]-How to use "AND" in a Django filter?
-2π
You probably want to have south_migrationhistory in both databases, so syncdb to βgistβ for south app. Then your migration should go just fine.
- [Django]-ImportError: No module named django.core.handlers.wsgi in install django mod_wsgi config on apache
- [Django]-What's the proper way to test token-based auth using APIRequestFactory?
- [Django]-Celery and Django simple example