如何使用django和or flask强制执行Postgres中的只读副本的读取?

问题描述 投票:1回答:1

是否从读取副本执行读取应用程序层任务?

即我有一个Postgres数据库,我已经设置了一个只读副本。

在应用程序端,我有两个连接,一个用于“写入”数据库,另一个用于“只读复制”数据库。

在我的代码中,如果我执行“读取”操作,则使用与只读副本的连接。但是当我去插入或更新时,我使用连接到“写”数据库a.k.a. master。

使用django或flask更好,这是自动管理的。即

我宁愿避免在代码中直接指定要使用的连接,只需让django或flask自己解决。

python django postgresql flask
1个回答
6
投票

Django的

为此,django支持所谓的数据库路由器。

首先创建自定义路由器:

class CustomRouter:
    def db_for_read(self, model, **hints):
        return 'replica'

    def db_for_write(self, model, **hints):
        return 'master'

并配置django orm来使用它。

DATABASES = {
    'default': {},
    'primary': {
        'NAME': 'master',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'spam',
    },
    'replica1': {
        'NAME': 'replica',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'eggs',
    },

}

DATABASE_ROUTERS = ['path.to.CustomRouter']

示例代码取自the docs(值得一读!)并稍作调整。

SQLAlchemy(烧瓶)

我浏览了SQLAlchemy文档并找到了this article的链接,该链接描述了如何使用SQLAlchemy实现djangos数据库路由器方法。

您可以在此处使用自定义会话来正确实现此功能。

从链接的文章中挑选以下片段并稍作调整。

创建你的引擎:

engines = {
    'master': create_engine('postgresql://user:***@localhost:5432/master',
                            logging_name='master'),
    'replica': create_engine('postgresql://user:***@localhost:5432/replica',
                             logging_name='replica'),
}

创建自定义会话类:

class RoutingSession(Session):

    def get_bind(self, mapper=None, clause=None):
        if self._flushing:
            return engines['master']
        else:
            return engines['replica']

并像这样创建你的会话:

Session = scoped_session(sessionmaker(class_=RoutingSession, autocommit=True))

阅读文章了解详细信息和限制。

© www.soinside.com 2019 - 2024. All rights reserved.