APScheduler 只更新数据库一次

问题描述

我试图让 APScheduler 在我的 Flask 应用程序中每 5 分钟更新一次 Postgresql 数据库,但该数据库仅在第一次更新,所有后续时间都不会保存更改。 APScheduler 本身就可以正常工作,如果将更新数据库功能换成显示文本的功能,那么每次都可以正常工作。

在我的应用程序中使用 Flask-sqlAlchemy:

sqlALCHEMY_DATABASE_URI = 'postgresql+psycopg2://postgres:name@localhost/name'

APScheduler 代码如下所示:

from apscheduler.schedulers.blocking import BlockingScheduler

sched = BlockingScheduler(daemon=True)
sched.add_job(func=update,trigger='interval',minutes=5)
sched.start()

数据库更新函数如下所示:

def update():
    for i in data:
        for row in Names.query:
            if row.id == i['id']:
                row.name = i['name']
                row.gender = i['gender']
                row.age = i['age']
    db.session.commit()

在日志中,APScheduler 总是成功运行。我还查看了 Postgresql 日志,在那里我发现了这句话:“远程主机强制关闭了现有连接。”

我怀疑可能是数据库引擎和会话,但我还没有在 Flask-sqlAlchemy 包中找到我需要实现的说明。

包的版本:

Flask-sqlAlchemy==2.4.1
sqlAlchemy==1.3.17
APScheduler==3.6.3

数据库模型:

class Names(db.Model):
    __searchable__ = ['name','age']
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(40))
    gender = db.Column(db.String(40))
    age = db.Column(db.Numeric)
   
    def __repr__(self):
        return '<Names %r>' % self.id

解决方法

我想我想出了问题所在。 APScheduler 以某种方式在第一次使用变量时缓存它的内容,然后只使用该值。 在函数之前,我有以下代码:

request = requests.get('https://privateapi')
data = request.json()

然后函数从数据中获取数据:

def update():
    for i in data:
        for row in Names.query:
            if row.id == i['id']:
                row.name = i['name']
                row.gender = i['gender']
                row.age = i['age']
    db.session.commit()

根据Flask-SQLAlchemy的日志,数据写入数据库成功。我尝试添加到打印(数据)函数,以便它每 5 分钟向我显示数据变量的内容,我看到它的内容没有更新。

结果是数据被写入数据库,但具有相同的值,所以我没有看到它的更新。

然后我尝试缩短请求路径而不是将其内容保存到变量中:

def update():
    for i in requests.get('https://privateapi').json():
        for row in Names.query:
            if row.id == i['id']:
                row.name = i['name']
                row.gender = i['gender']
                row.age = i['age']
    db.session.commit()

但这里没有任何改变。

更新: 我通过删除函数末尾的数据变量解决了这个问题:

def update():
    name = requests.get('https://privateapi').json()
    for i in name:
        for row in Names.query:
            if row.id == i['id']:
                row.name = i['name']
                row.gender = i['gender']
                row.age = i['age']
    del name
    db.session.commit()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...