如何使数据库查询引用保持最新

时间:2018-04-29 16:59:42

标签: flask

我正在创建一个带有两个面板的烧瓶应用程序,一个用于管理员,另一个用于用户。在app方案中,我有一个实用程序文件,除了其他函数之外,我保留了大部分冗余变量,(冗余我的意思是我在应用程序的许多不同部分使用它)

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 :(得分:1)

您正在尝试将高级逻辑添加到一个简单变量:您只想查询数据库一次,并通过重新加载模块来定期强制更新变量。这不是应该如何使用模块和导入机制。

如果要从数据库中访问可能更改的值,则必须反复阅读。

解决方案是,而不是变量,定义一个函数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