Django阻止远程数据库上的迁移

时间:2017-11-01 01:59:03

标签: python django django-models multiple-databases django-database

我有一个连接到两个数据库的Django应用程序。我的一个DB位于不同的(生产)服务器上。我想确保在开发我的应用程序时,我不会意外地在生产服务器上迁移模型。我的理解是这样的:假设我的settings.py DATABASES是这样的:

BigDecimal.compare

现在假设我还有一个名为RemoteDBRouter的路由器类。与所有路由器一样,该类将具有allow_migrate方法。请注意,远程数据库使用Django auth模型,因此用户模型将具有app_label' auth'并且远程数据库也有自己的app_label' remoteapp'。有了这些信息,我看到了allow_migrate方法的两种可能性:

DATABASES = {
    'default': {},
    'remote_db': {
        'NAME'    : 'important_remote_db_name',
        'ENGINE'  : 'django.db.backends.mysql',
        'USER'    : 'someuser',
        'PASSWORD': 'somepass',
        'HOST'    : 'some.production.host.com',
        'PORT'    : '3306',
    },
    'myapp_db': {
        'NAME'    : 'my_app_db_name',
        'ENGINE'  : 'django.db.backends.mysql',
        'USER'    : 'localuser',
        'PASSWORD': 'localpassword'
    }
}

我应该使用哪一个?选项2更容易,因为它只是说我不应该迁移app_label表示模型来自远程数据库的任何模型。选项1进行额外的检查以查看db字段是否是' remote_db' (我假设我们需要检查' remote_db'而不是' remote_db_name')。我使用哪一个是否重要?我担心如果我使用选项1并且数据库检查失败,该方法将返回None,然后Django代码将检查下一个路由器类,其中allow_migrate可能返回True。

1 个答案:

答案 0 :(得分:2)

您希望RemoteDBRouterremote_db数据库具有权威性。您不希望从authremoteapp或其他应用程序控制本地计算机的迁移。其他数据库不一定由RemoteDBRouter控制。因此,您从:

开始
    if db == 'remote_db':
        return False

问题是,如果您希望在开发写入操作时有时将authremoteapp切换到本地,或者您希望只有只读访问权限,那么这些表永远不需要在本地创建。然后你可以添加:

    if app_label == 'auth' or app_label == 'remoteapp':
        return False

其他数据库的迁移可以由默认路由器或其他路由器控制:

    return None

在本地创建测试数据库的测试更复杂。

DATABASES = {
    'remote_db': {
        ...
        'HOST': 'some.production.host.com',
        'USER': 'some_readonly_user',   # read-only for security
        'TEST': {
            'HOST': 'localhost',
            ...
        }
    }
}

您也可以选择通过路由器规则支持对远程数据库的只读访问:

def db_for_write(model, **hints):
    if model._meta.app_label in ('auth', 'remoteapp'):
        return 'myapp_db'  # or maybe the db 'default' where the model doesn't exist

如果您错误地写作,则例外优于损害生产数据。路由器可以通过多种方式覆盖,例如:通过using=db参数或.using(db)方法。为安全起见,连接应由只读用户进行。