Как поддерживать ссылки на запросы к базе данных в актуальном состоянии - PullRequest
0 голосов
/ 29 апреля 2018

Я создаю колбу с двумя панелями, одна для администратора, а другая для пользователей. В схеме приложения у меня есть файл утилит, в котором я храню большинство избыточных переменных помимо других функций (под избыточностью я подразумеваю, что я использую его во многих различных частях приложения)

utilities.py

# ...
opening_hour = db_session.query(Table.column).one()[0]  # 10:00 AM
# ...

Значение Table.column или, скажем, значение переменной opening_hour, указанное выше, вводится администратором в базу данных через его / ее веб-панель. Это значение ограничивает доступ пользователей к определенным функциям приложения до указанного часа.

Проблема:

Если администратор изменит это значение через свою веб-панель, скажем, 11:00 AM. изменения не отображаются непосредственно на панели пользователей. «Даже если они были внесены в базу данных!».

Если я хочу, чтобы новое значение opening_hour взяло под свой контроль. Я должен вручную закрыть приложение и перезапустить его «иногда даже это не работает»

Я пытался добавить gc.collect() ... ничего не сделал. Там должен быть способ обойти это, кроме закрытия и перезапуска приложения вручную. Во-первых, я сомневаюсь, что администратор сможет это сделать. во-вторых, даже если он / она может, это было бы очень сложно.

Если кто-то может относиться к этому, пожалуйста, объясните, почему это происходит и как обойти это. Заранее спасибо:)

1 Ответ

0 голосов
/ 01 мая 2018

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

Если вы хотите получить доступ к изменяющемуся значению из базы данных, вы должны читать его снова и снова.

Решение состоит в том, чтобы вместо переменной определить функцию opening_hours, которая выполняет запрос к БД каждый раз, когда вы проверяете значение

def opening_hours():
    return (
        db_session.query(Table.column).one()[0],  # 10:00 AM
        db_session.query(Table.column).one()[1]   # 5:00 PM
    )

Теперь вам может не потребоваться запрашивать базу данных каждый раз, когда вы проверяете значение, но, возможно, кэшируйте ее на несколько минут. Для этого проще всего использовать cachetools:

import cachetools

cache = cachetools.TTLCache(maxsize=10, ttl=60) # Cache for 60 seconds

@cachetools.cached(cache)
def opening_hours():
    return (
        db_session.query(Table.column).one()[0],  # 10:00 AM
        db_session.query(Table.column).one()[1]   # 5:00 PM
    )

Кроме того, поскольку вы используете Flask, вы можете создать декоратор маршрута, который контролирует доступ к вашим представлениям в зависимости от вида дня

from datetime import datetime, time
from functools import wraps
from flask import g, request, render_template

def only_within_office_hours(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        start_time, stop_time = opening_hour()
        if start_time <= datetime.now().time() <= stop_time:
            return render_template('office_hours_error.html')
        return f(*args, **kwargs)
    return decorated_function

, который вы можете использовать как

@app.route('/secret_page')
@login_required
@only_within_office_hours
def secret_page():
    pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...