Django - 多数据库 + 多模型

0 投票
1 回答
1306 浏览
提问于 2025-04-18 14:43

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

我想把这两个模型同步到两个数据库:管理员模型同步到数据库A,用户模型同步到数据库B。

所以我的问题是,如何把这两个模型同步到两个数据库呢?用户模型应该在默认数据库里,而管理员模型在管理员模型里。

这是我尝试过的:

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

使用south的时候,迁移文件是创建出来了,但当我执行迁移时,它返回一个错误,提示 south.db.db = south.db.dbs[database] KeyError: 'gor_vms'

另外,DATABASE_ROUTERS = ['manager.router.DatabaseAppsRouter'] 也报错,提示 No named module manager.router

我该如何把这两个数据库和两个不同的模型同步起来呢?

附注:我在StackOverflow上看了很多帖子,但没有找到正确的答案。请帮帮我。

编辑

我也尝试过这个。

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

设置

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

所以,为了同步数据库,我按照以下步骤操作:-

1) python manage.py schemamigration data --initial

2) python manage.py syncdb

它返回了一个追踪信息,提示:

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

我该如何在不同的数据库中使用不同的模型呢?请帮帮我。

1 个回答

0

在你的设置中,DATABASE_ROUTERS 列表应该包含的是 python 路径(比如:'modules.data.admin_db_router.AdminRouter', ...),而不是文件系统路径。需要注意的是,通常的 PYTHONPATH / sys.path 规则仍然适用,也就是说在上面的例子中,modulesdata 这两个文件夹必须是 Python 包,并且包含 modules 的那个文件夹必须以某种方式在你的 sys.path 中。

另外,Python 和 Java 不一样,所以你不需要为每个类创建一个不同的模块。我个人建议把 AdminRouterUserRouter 这两个类放在同一个 routers.py 模块里。

撰写回答