【问题标题】:django with multiple databases and foreignkeys for User具有多个数据库和用户外键的 django
【发布时间】:2018-04-13 06:23:04
【问题描述】:

假设我的服务器上有一个 django 应用程序,但我希望使用 django.contrib.auth.models 进行身份验证,其中用户和组模型/数据位于另一个数据库中的另一个服务器上。在 Django 中,我的 DATABASES 设置是这样的:

DATABASES = {
    'default': {},
    'auth_db': {
        'NAME'      : 'my_auth_db',
        'ENGINE'    : 'django.db.backends.mysql',
        'USER'      : 'someuser',
        'PASSWORD'  : 'somepassword',
        'HOST'      : 'some.host.com',
        'PORT'      : '3306',
    },
    'myapp': {
        'NAME': 'myapp_db',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'localuser',
        'PASSWORD': 'localpass',
    }
}

DATABASE_ROUTERS = ['pathto.dbrouters.AuthRouter', 'pathto.dbrouters.MyAppRouter']

第一个问题:这是否可行,即它是否允许我使用存储在远程数据库“my_auth_db”中的用户登录到我的 Django 应用程序?

假设上面的答案是肯定的,如果在我的本地数据库(应用程序“myapp”)中我的模型对用户具有外键,会发生什么情况?换句话说,我的模型 SomeModel 是在 myapp 中定义的,应该存在于 myapp_db 中,但它对 my_auth_db 中的用户有一个 ForeignKey:

class SomeModel(models.model):
    user = models.ForeignKey(User, unique=False, null=False)
    description = models.CharField(max_length=255, null=True)
    dummy = models.CharField(max_length=32, null=True)
    etc.

第二个问题:这是可能的,还是根本不可能一个 DB 表拥有另一个 DB 中的表的 ForeignKey?

如果我真的想完成这项工作,我是否可以将 ForeignKey 字段 'user' 替换为 IntegerField 'user_id',然后如果我需要 somemodel.user,我会改为获取 somemodel.user_id 并使用 models.User.objects。 get(pk=somemodel.user_id),路由器知道在哪里查询用户的 auth_db?这是一种可行的方法吗?

【问题讨论】:

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


    【解决方案1】:

    问题 1 的答案是:是的。

    在任何情况下,您都需要database router(Django 文档中的示例正是关于 auth 应用程序的,因此无需在此处复制此代码)。

    问题 2 的答案是:也许。不是正式的。这取决于您如何设置 MySQL:

    https://docs.djangoproject.com/en/dev/topics/db/multi-db/#limitations-of-multiple-databases

    Django 目前不为外键或跨多个数据库的多对多关系提供任何支持

    这是因为参照完整性

    但是,如果您使用 SQLite 或 MySQL 和 MyISAM 表,则没有强制引用完整性;因此,您可能能够“伪造”跨数据库外键。但是,这个配置并没有被 Django 官方支持。

    我有几个旧版 MySQL 数据库(只读)的设置。这个答案显示How to use django models with foreign keys in different DBs?

    我后来遇到了Django ManyToMany through with multiple databases 的麻烦,解决方案(如那里接受的答案所述)是用引号设置表名:

    class Meta:    
        db_table = '`%s`.`table2`' % db2_name
    

    可能提供一些额外信息的相关问题:

    How to work around lack of support for foreign keys across databases in Django

    How to use django models with foreign keys in different DBs?

    如果有人将所有这些信息放入官方 Django 文档中,那就太好了 :-)

    【讨论】:

    • 这是很好的信息,谢谢!从我在这里看到的情况来看,人们似乎创建了各种有些复杂的解决方案,只是为了能够使用 somemodel.user 语法访问模型。由于这只是一个测试应用程序,我想我将使用一个普通的 IntegerField 并存储 user_id 并有一些单独的函数(例如)为 somemodel 获取用户,如下所示: user=User.objects.get(pk=somemodel.user_id )。看起来这仍然有效。它不具有引用完整性,即如果有人删除了一个用户,那么这种方法不会自动删除我的带有 user_id 的 SomeModel 实例。
    • 是的,这些都是复杂的解决方法,但是所有的变更请求都会被 Django 拒绝,所以这就是我们所坚持的......如果性能不是那么大的问题,user=User.... 方法没问题,但它会触发一个额外的查询来读取您正在访问的每个对象的用户,而一个跨越的 ForeignKey 可以在一个查询中执行它(前提是 DB 在同一台服务器上)
    猜你喜欢
    • 1970-01-01
    • 2012-03-16
    • 2011-10-23
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    相关资源
    最近更新 更多