【问题标题】:Django manually select multiple databasesDjango 手动选择多个数据库
【发布时间】:2015-02-06 20:25:04
【问题描述】:

好吧,看完文档https://docs.djangoproject.com/en/1.6/topics/db/multi-db/

我了解开发人员可以手动选择数据库进行选择、保存和删除的方式。我的问题是有没有更简单的方法来做到这一点?

我的意思是 django 有类似事务管理的功能吗?

with transaction.atomic():
    do_something()

因此,特定部分下的所有代码都在一个与特定数据库对话的事务中,例如

with using(default):
    do_something()

如果django没有这种包装器,有什么好的方法可以实现我描述的吗?

【问题讨论】:

标签: django


【解决方案1】:

我不相信有。您可以将 DATABASES 设置设置为可以更改默认值的自定义类 dict 类,即:

from threading import local

class DatabaseSettings(dict):
    def __init__(self, db, *args, **kwargs):
        super(DatabaseSettings, self).__init__(*args, **kwargs)
        self._default = local()
        self._default.db = db

    def set_database(self, db):
        self._default.db = db

    def __getitem__(self, name):
        if name == DEFAULT_DB_ALIAS and self._default.db:
            name = self._default.db
        return super(DatabaseSettings, self).__getitem__(name)


from django.conf import settings
from django.utils import six
from django.db import connections, DEFAULT_DB_ALIAS


class UseDatabase(object):
    def __init__(self, db):
        self.db = db

    def __enter__(self):
        settings.DATABASES.set_database(self.db)
        conn = getattr(connections._connections, self.db, None)
        if conn:
            setattr(connections._connections, DEFAULT_DB_ALIAS, conn)

    def __exit__(self, exc_type, exc_value, traceback):
        settings.DATABASES.set_database(None)
        if exc_type:
            six.reraise(exc_type, exc_value, traceback)

connections._connections 已经是线程本地的,所以这应该是线程安全的。请仔细检查,因为我远非多线程专家。

现在您可以使用with UseDatabase('<name>'): 指定不同的数据库作为该块的默认值。这不会改变显式使用不同数据库的代码的行为。

这段代码远未完成,但它应该让您开始。确保您实际保存和恢复旧的默认连接,也许支持嵌套上下文管理器是个好主意。

【讨论】:

    猜你喜欢
    • 2015-09-11
    • 2013-08-15
    • 2011-04-14
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    相关资源
    最近更新 更多