使用Django扩展Disqus,水平和垂直分区的辅助方法,请解释

1 投票
1 回答
1156 浏览
提问于 2025-04-16 06:17

http://www.slideshare.net/zeeg/djangocon-2010-scaling-disqus

这是一个关于垂直分区的辅助工具:

class ApplicationRouter(object)

    def db_for_read(self, model, **hints):

        instance = hints.get('instance')

        if not instance:
            return None

        app_label = instance._meta.app_label

        return get_application_alias(app_label)

有人能解释一下这段代码在做什么吗?

接下来是关于水平分区的内容:

class ForumPartitionRouter(object):

    def db_for_read(self, model, **hints):

        instance = hints.get('instance')

        if not instance:
            return None

        forum_id = getattr(instance, 'forum_id', None)

        if not forum_id:
            return None

        return get_forum_alias(forum_id)

我大概明白这些代码在做什么,但有些行我不太确定,比如:

instance = hints.get('instance')

1 个回答

2

他在讨论Disqus是如何利用Django 1.2及以上版本中的数据库路由技术的,这种技术允许你同时连接多个数据库。与早期版本的Django不同,Django 1.2及以上版本使用的是一个字典的字典,外层字典的键是一个令牌,用来标识数据库,而内层字典的键则对应于早期版本Django中的常见设置。

ForumPartitionRouter是一个比较明显的例子:不同的论坛存储在不同的数据库中(这点很有趣,因为这表明他们有一些很棒的管理工具,可以在服务器启动时定义这些分区,把每个Django实例当作他们系统中一个临时的对象),服务器使用forum_id来找到正确的数据库,从中获取相关的论坛成员(在这个例子中,就是帖子)。db_for_read()会返回一个指向数据库的令牌。

许多论坛有很多帖子,但每个帖子只属于一个论坛。由于论坛之间没有相互关系,你可以把每个论坛及其帖子存储在一个数据库中,完全独立于其他论坛及其帖子。

如果你查看第23页的例子,可以清楚地看到:

forum.post_set.all()

... 发生的事情是论坛的object_id被用作在某个表中查找与论坛ID相关的数据库(不是表,而是数据库),这些数据库可能在网络的其他地方。

因此,我觉得ApplicationRouter在处理关系时也做了类似的事情。看看这段文字:“垂直分区涉及创建列数较少的表,并使用额外的表来存储剩余的列。”这正是ApplicationRouter所做的:当你使用一个应用程序,并且想要访问不同表中的相关对象时,ApplicationRouter会查看请求和需要填充的实例,并使用类似于ForumPartitionRouter的查找表返回一个指向包含相关实例详细信息的数据库的键。

你可以在这里查看多数据库的相关内容:

http://docs.djangoproject.com/en/dev/topics/db/multi-db/

撰写回答