Python Django ORM выбирает пользовательскую БД для необработанного запроса по переменной сессии

Учитывая следующий необработанный запрос, внутри представления:

@login_required(login_url='/login/')
def view(request):
    result = CustomObject.objects.raw("SELECT a, b, c FROM table WHERE d = %(param)s", {
        'param': 123
    })

    ...

    return render(request, 'templates/template.html', {
        'a': 'b'
    })

Я использую маршрутизатор для маршрутизации запроса к БД (вариант использования - только чтение).

class MyDBRouter(object):
    @staticmethod
    def db_for_read(model, **hints):
        if model == CustomObject:
            return 'customdb'
        return None

    @staticmethod
    def db_for_write(model, **hints):
        return None

У меня настроены доступные базы данных:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    },
    'customdb': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'xxx.yyy.zzz:1234/DB',
        'USER': 'user',
        'PASSWORD': 'pass',
    }
}

Проблема:

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

Вопрос:

  • Как я могу получить доступ к переменным сессии из статического метода маршрутизатора?
  • Если использование маршрутизаторов не рекомендуется в данном конкретном случае, какие еще варианты решения этой проблемы у меня есть?

Я не думаю, что вам нужно делать так

Если вам нужно использовать пользовательскую базу данных на лету, вы можете передать ее в

def login(request):
    # Your logic
    request.session["db-name"] = "customdb"
    # Your logic

def query_view(request):
    db_name = request.session.get("db-name", "default")
    # execute your query with this db_name like 

    MyModel.objects.using(db_name).raw("Your query")

Также, если вы хотите, чтобы ключ сессии был уникальным, вы можете использовать уникальное имя пользователя, как это

request.session[f"{request.user.username}_{db_name}"] = "customdb"

И обращаться к нему в других представлениях.

Вернуться на верх