问题
I have two databases and two models:one the admin and the is user.
I want to sync my models to the two databases; admin model to database A and user model to database B;
so my problem the how to sync the two models to two databases? User should in default DB and admin in admin model.
Here's what I've tried:-
class User(models.Model):
job_id = models.CharField(max_length = 255)
time = models.DateTimeField( auto_now_add = True, db_index = True)
class Meta:
app_label = 'user_data'
class Admin(models.Model):
barcode = models.CharField(max_length = 255)
weight = models.CharField(max_length = 255)
length = models.CharField(max_length = 255)
breadth = models.CharField(max_length = 255)
height = models.CharField(max_length = 255)
dsp_name = models.CharField(max_length = 255)
time = models.DateTimeField( auto_now_add = True, db_index = True)
class Meta:
app_label = 'admin_data'
Here are my settings:-
DATABASE_ROUTERS = ['manager.router.DatabaseAppsRouter']
DATABASE_APPS_MAPPING = {
'user_data': 'default',
'admin_data':'admin_db'
}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'gor_vms',
'USER': 'root',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': '',
},
'admin_db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'admin_vms_db',
'USER': 'root',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': '',
}
}
Upon using south, the migrations are created but when I migrate it it returns an error. saying south.db.db = south.db.dbs[database]
KeyError: 'gor_vms'
Also, DATABASE_ROUTERS = ['manager.router.DatabaseAppsRouter']
throws an error saying No named module manager.router
How do I sync the 2 DB's with 2 different models.
PS: I've read various threads on SO, but didnt got the correct answer. Kindly help
EDIT
I've tried this as well.
AdminRouter
class AdminRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'admin_data':
return 'admin_db'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'admin_data':
return 'admin_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'admin_data' or \
obj2._meta.app_label == 'admin_data':
return True
return None
def allow_migrate(self, db, model):
if db == 'admin_db':
return model._meta.app_label == 'admin_data'
elif model._meta.app_label == 'admin_data':
return False
return None
GorRouter
class UserRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'user_data':
return 'default'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'user_data':
return 'default'
return None
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'user_data' or \
obj2._meta.app_label == 'user_data':
return True
return None
def allow_migrate(self, db, model):
if db == 'default':
return model._meta.app_label == 'user_data'
elif model._meta.app_label == 'user_data':
return False
return None
SETTINGS
DATABASE_ROUTERS = ['../modules/data/admin_db_router.AdminRouter','../modules/data/user_db_router.UserRouter']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'gor_vms',
'USER': 'root',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': '',
},
'admin_db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'admin_vms_db',
'USER': 'root',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': '',
}
}
So, to sync up the DB, I following these steps:-
1) python manage.py schemamigration data --initial
2) python manage.py syncdb
It returns a traceback saying:-
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 242, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 285, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 415, in handle
return self.handle_noargs(**options)
File "/usr/local/lib/python2.7/dist-packages/south/management/commands/syncdb.py", line 92, in handle_noargs
syncdb.Command().execute(**options)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 285, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 415, in handle
return self.handle_noargs(**options)
File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/syncdb.py", line 61, in handle_noargs
seen_models = connection.introspection.installed_models(tables)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/__init__.py", line 1254, in installed_models
if router.allow_syncdb(self.connection.alias, model):
File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 272, in allow_syncdb
for router in self.routers:
File "/usr/local/lib/python2.7/dist-packages/django/utils/functional.py", line 49, in __get__
res = instance.__dict__[self.func.__name__] = self.func(instance)
File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 230, in routers
router = import_by_path(r)()
File "/usr/local/lib/python2.7/dist-packages/django/utils/module_loading.py", line 21, in import_by_path
module = import_module(module_path)
File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 33, in import_module
raise TypeError("relative imports require the 'package' argument")
TypeError: relative imports require the 'package' argument
How would I get different models in different DB's. Kindly help.
回答1:
In your settings, the DATABASE_ROUTERS
list should contain python path (ie : 'modules.data.admin_db_router.AdminRouter', ...
), not filesystem path. Note that usual PYTHONPATH / sys.path
requirements apply, ie in the above example the modules
and data
directories must be python packages and the directory containing modules
must be in your sys.path
one way or another.
As a side note, Python is not Java so you don't need a different module per class. I'd personally put both AdminRouter
and UserRooter
classes in a same routers.py
module.
来源:https://stackoverflow.com/questions/24952605/django-multiple-db-multiple-models