本文介绍了Django - 多个DB +多模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个数据库和两个模型:一个是管理员,也就是用户。



我想将我的模型同步到两个数据库;管理员模型到数据库A和用户模型到数据库B;



所以我的问题如何将两个模型同步到两个数据库?用户应该在管理模式中默认为DB和admin。



这是我试过的: -

  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'

这是我的设置: -

  DATABASE_ROUTERS = ['manager.router.DatabaseApps路由器'] 
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':'',
}
}
使用南方时,m已经创建了一个数据,但是当我迁移它时会返回一个错误。说 south.db.db = south.db.dbs [database]
KeyError:'gor_vms'



另外, DATABASE_ROUTERS = ['manager.router.DatabaseAppsRouter'] 抛出一个错误,说没有命名的模块manager.router



如何将2个DB与2个不同的模型进行同步。



PS:I在SO上读过各种线程,但没有得到正确答案。请帮助



编辑



我也尝试过这个。 p>

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):
如果obj1._meta.app_label =='admin_data'或\
obj2._meta.app_label =='admin_data ':
return True
return无

def allow_migrate(self,db,model):

如果db =='admin_db':
return model._meta.app_label =='admin_data'
elif model._meta.app_label =='admin_数据':
return False
return无

GorRouter

  class UserRouter(object):
def db_for_read(self,model,** hints):
如果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):
如果obj1._meta.app_label =='user_data'或\
obj2._meta.app_label =='user_data':
返回True
返回无

def allow_migrate(self,db,model):

如果db =='default':
返回model._meta.app_label =='user_data'
elif模型._meta.app_label =='user_data':
ret urn False
返回无

设置

  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':'',
}
}

所以,要同步DB,我按照这些步骤: -
1) python manage.py schemamigration data --initial



2) python manage.py syncdb



它返回一个追溯说: -

 追溯(最近的最后一次呼叫):
文件manage.py,第10行,< module>
execute_from_command_line(sys.argv)
文件/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py,第399行,execute_from_command_line
utility.execute()
文件/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py,第392行,执行
self.fetch_command (子命令).run_from_argv(self.argv)
文件/usr/local/lib/python2.7/dist-packages/django/core/management/base.py,第242行,在run_from_argv
self.execute(* args,** options .__ dict__)
文件/usr/local/lib/python2.7/dist-packages/django/core/management/base.py,第285行,执行
output = self.handle(* args,** options)
文件/usr/local/lib/python2.7/dist-packages/django/core/management/base.py, line 415,in handle
return self.handle_noargs(** options)
文件/usr/local/lib/python2.7/dist-packages/south/management/commands/syncdb.py,第92行,在handle_noargs
syncdb.Command()。execute(** options )
文件/usr/local/lib/python2.7/dist-packages/django/core/management/base.py,第285行,执行
output = self.handle(* args ,** options)
文件/usr/local/lib/python2.7/dist-packages/django/core/management/base.py,第415行,处理
return self.handle_noargs (** options)
文件/usr/local/lib/python2.7/dist-packages/django/core/management/commands/syncdb.py,第61行,handle_noargs
seen_models = connection.introspection.installed_models(tables)
文件/usr/local/lib/python2.7/dist-packages/django/db/backends/__init__.py,第1254行,installed_models
if router.allow_syncdb(self.connection.alias,model):
文件/usr/local/lib/python2.7/dist-packages/django/db/utils.py,第272行,allow_syncdb
for self.routers中的路由器:
文件/usr/local/lib/python2.7/dist-packages/django/utils/functional.py,第49行,__get__
res =实例.__ dict __ [self.func .__ name__] = self.func(instance)
文件/usr/local/lib/python2.7/dist-packages/django/db/utils.py,行230,路由器
router = import_by_path(r)()
文件/ usr / local / lib / python2.7 / dist-packages / django / utils / module_loading.py,第21行import_by_path
module = import_module(module_path)
文件/ usr / local / lib /python2.7/dist-packages/django/utils/importlib.py,第33行,import_module
raise TypeError(相对导入需要package参数)
TypeError:相对导入要求'package'参数

如何在不同的数据库中获取不同的模型。请妥善协助。

解决方案

在您的设置中, DATABASE_ROUTERS python 路径(即:'modules.data.admin_db_router.AdminRouter',... ),而不是文件系统路径。请注意,通常的PYTHONPATH / sys.path 要求适用,即在上述示例中,模块数据目录必须是python包,包含 modules 的目录必须位于您的 sys



作为一个附注,Python不是Java,因此您不需要每个类别的不同模块。我个人将 AdminRouter UserRooter 在同一个 routes.py 模块。


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.

解决方案

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.

这篇关于Django - 多个DB +多模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 20:30