首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Django中跨数据库“匹配”/relations数据

在Django中跨数据库“匹配”/relations数据
EN

Stack Overflow用户
提问于 2014-07-08 09:51:45
回答 3查看 772关注 0票数 4

在开发索引系统文档的网站时,我遇到了一个棘手的难题,就是在Django的数据库中,数据“匹配”/relations。

本地数据库的简化模型:

代码语言:javascript
复制
from django.db import models

class Document(models.Model):
    name = models.CharField(max_length=200)
    system_id = models.IntegerField()
    ...

想象中的模型,系统细节存储在一个远程数据库中。

代码语言:javascript
复制
from django.db import models               

class System(models.Model):     
    name = models.CharField(max_length=200)           
    system_id = models.IntegerField()      
    ...

这个想法是,在我的网站上创建一个新的文档条目时,相关系统的ID将存储在本地数据库中。在显示数据时,我必须使用存储的ID从远程数据库检索系统名称和其他详细信息。

我已经调查过跨数据库的外键,但这似乎是非常广泛的,我不确定我是否想要关系。相反,我在文档模型/类中可视化了一个函数,它能够检索匹配的数据,例如通过导入自定义路由器/函数。

我该怎么解决这个问题?

请注意,我无法更改远程数据库上的任何内容,而且它是只读的。不确定我是否也应该为系统创建一个模型。这两个数据库都使用PostgreSQL,但是我的印象是,它与使用数据库的这个场景并不真正相关。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-10 13:40:38

在django文档多数据库(手动选择数据库)

代码语言:javascript
复制
# This will run on the 'default' database.
Author.objects.all()

# So will this.
Author.objects.using('default').all()

# This will run on the 'other' database.
Author.objects.using('other').all()

The 'default' and 'other' are aliases for you databases.
In your case it would could be 'default' and 'remote'.

当然,您可以将.all()替换为您想要的任何东西。

代码语言:javascript
复制
Example: System.objects.using('remote').get(id=123456)
票数 4
EN

Stack Overflow用户

发布于 2014-07-15 15:48:33

您是正确的,跨数据库的外键在Django ORM中是一个问题,在某种程度上也是db级别的问题。

您已经得到了基本的答案:“我在文档模型/类中可视化了一个函数,它能够检索匹配的数据”。

我会这样做:

代码语言:javascript
复制
class RemoteObject(object):
    def __init__(self, remote_model, remote_db, field_name):
        # assumes remote db is defined in Django settings and has an
        # associated Django model definition:
        self.remote_model = remote_model
        self.remote_db = remote_db
        # name of id field on model (real db field):
        self.field_name = field_name
        # we will cache the retrieved remote model on the instance
        # the same way that Django does with foreign key fields:
        self.cache_name = '_{}_cache'.format(field_name)

    def __get__(self, instance, cls):
        try:
            rel_obj = getattr(instance, self.cache_name)
        except AttributeError:
            system_id = getattr(instance, self.field_name)
            remote_qs = self.remote_model.objects.using(self.remote_db)
            try:
                rel_obj = remote_qs.get(id=system_id)
            except self.remote_model.DoesNotExist:
                rel_obj = None
            setattr(instance, self.cache_name, rel_obj)
        if rel_obj is None:
            raise self.related.model.DoesNotExist
        else:
            return rel_obj

    def __set__(self, instance, value):
        setattr(instance, self.field_name, value.id)
        setattr(instance, self.cache_name, value)


class Document(models.Model:
    name = models.CharField(max_length=200)
    system_id = models.IntegerField()
    system = RemoteObject(System, 'system_db_name', 'system_id')

您可能会意识到,上面的RemoteObject类实现了Python的描述符协议,请参阅这里获得更多信息:

https://docs.python.org/2/howto/descriptor.html

示例用法:

代码语言:javascript
复制
>>> doc = Document.objects.get(pk=1)
>>> print doc.system_id
3
>>> print doc.system.id
3
>>> print doc.system.name
'my system'
>>> other_system = System.objects.using('system_db_name').get(pk=5)
>>> doc.system = other_system
>>> print doc.system_id
5

更进一步,您可以编写一个自定义db路由器:

https://docs.djangoproject.com/en/dev/topics/db/multi-db/#using-routers

这将使您能够通过将System模型的所有读取路由到适当的db来消除代码中的System调用。

票数 2
EN

Stack Overflow用户

发布于 2014-07-14 20:18:37

我会选择一个方法get_system()。所以:

代码语言:javascript
复制
class Document:
    def get_system(self):
       return System.objects.using('remote').get(system_id=self.system_id)

这是最简单的解决办法。一个可能的解决方案也是使用PostgreSQL的外部数据包装功能。通过使用FDW,您可以从django抽象出多数据库处理,并在数据库中进行--现在您可以使用需要使用文档->系统关系的查询。

最后,如果您的用例允许,只需定期将系统数据复制到本地db即可是一个很好的解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24628777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档