Django手动选择多个数据库

时间:2015-02-06 20:25:04

标签: django

那么,在阅读了文档https://docs.djangoproject.com/en/1.6/topics/db/multi-db/

之后

我理解开发人员可以手动选择数据库进行选择,保存和删除的方式。我的问题是,有更简单的方法吗?

我的意思是django有类似于它的交易管理吗?

with transaction.atomic():
    do_something()

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

with using(default):
    do_something()

如果django没有这种包装,有没有什么好方法可以实现我所说的呢?

1 个答案:

答案 0 :(得分:0)

我不相信有。您可以将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>'):指定其他数据库作为该块的默认值。这不会改变显式使用不同数据库的代码的行为。

这段代码远未完成,但应该给你一个开始。确保您实际保存并恢复旧的默认连接,并且支持嵌套上下文管理器可能是个好主意。