2015-02-06 10 views
2

Ну, после прочтения док https://docs.djangoproject.com/en/1.6/topics/db/multi-db/Django вручную выбрать несколько баз данных

Я понимаю так, что разработчик может вручную выбрать базу данных для выбора, сохранения и удаления. Мой вопрос в том, что есть более простой способ сделать это?

Я имею в виду, что у django есть что-то вроде управления транзакциями?

with transaction.atomic(): 
    do_something() 

Так весь код под конкретный раздел в одной транзакции, разговаривая с одной конкретной базы данных, как

with using(default): 
    do_something() 

Если Джанго не имеет такого рода обертке, есть ли хороший способ для достижения того, что я описал?

+0

Это может помочь вам: http://stackoverflow.com/questions/21861207/is-transaction-atomic-same-as-transaction-commit-on-success –

ответ

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>'): для указания другой базы данных по умолчанию для этого блока. Это не изменит поведение кода, который явно использует другую базу данных.

Этот код далеко не полный, но он должен дать вам начало. Убедитесь, что вы фактически сохраняете и восстанавливаете старое подключение по умолчанию, и, возможно, это хорошая идея для поддержки вложенных менеджеров контекста.

Смежные вопросы