Flask-Sqlalchemy:数据库查询不返回新数据

Posted

技术标签:

【中文标题】Flask-Sqlalchemy:数据库查询不返回新数据【英文标题】:Flask-Sqlalchemy: DB queries don't return new data 【发布时间】:2015-10-18 11:56:42 【问题描述】:

我正在构建一个应用程序,它从一项服务接收 webhook,将数据存储在数据库中,然后通过 API 提供数据。

我能够成功地将数据添加到我的应用程序中,但是当我查询数据库时,我只收到了上次启动应用程序时数据库中的第一次提交。

例如,如果我启动应用程序时 Orders 表中有 26 个订单,然后触发 webhook,Order.query.all() 将返回 27 个订单,直到我重新启动应用程序,无论表中实际有多少订单 (我可以使用 mysql 进行验证)。

这是一个用于向表中插入数据的类的示例:

@webhook.route('/order/insert', methods=['POST'])
def insert_orders():
    soda_json = request.json
    db.session.add(Order(
        order_id=soda_json['id'],  
        created_at=datetime.datetime.now(),
        currency=soda_json['currency'],
        total_line_items_price=soda_json['total_line_items_price'],
        refunds=sum(float(i) for i in soda_json['refunds'] if soda_json['refunds']),
        shipping_lines_price=sum([float(line['price']) for line in soda_json['shipping_lines']]),
        note=soda_json['note']
    ))
db.session.commit()
return '200'

这是我用于测试的基本 API 方法:

order_test = Order.query.all()

@api.route('/display', methods=['POST', 'GET'])
def display_test():
    return jsonify(json_list=[i.serialize for i in order_test]), '200'

为了始终获取最新数据,我缺少什么?

【问题讨论】:

如何填充order_test?你能提供从数据库中填充它的代码吗 刚刚添加的order_test 试试return jsonify(json_list = order_test)。如果这不起作用,请尝试return jsonify(json_list = order_test.all()) 【参考方案1】:

据我所知,order_list 仅在启动该视图时才被填充。因此,如果您将该行代码移动到您的路由调用中,那么每次调用该路由时都会刷新它。

例如

@api.route('/display', methods=['POST', 'GET'])
def display_test():
    order_test = Order.query.all()
    return jsonify(json_list=[i.serialize for i in order_test]), '200'

从您目前所说的看来,无论新数据发送到网络挂钩多少次,您似乎只能向数据库添加一条新记录,并且如果您重新启动 API,那么您就是回到第一格,新记录不再存在。

对我来说,在 webhook 中提交事务似乎是一个问题,因为在调用 db.session.add() 之后,数据不会保存到数据库中,因此事务保持打开状态,因此当添加新数据时,它可能会覆盖上一次调用中的数据,然后当您结束 API 时,事务要么 committed 要么 rollbacked(可以'不记得烧瓶炼金术的默认动作)。您可能需要检查数据本身并查看调用 webhook 后第 51 行中返回的数据,并查看在将新数据发送到 webhook 后它是否发生变化。

如果您还比较上面的 webhook 代码和下面的提交和返回行是不同的。在您的情况下,它们位于不同的选项卡行上,并且在 webhook 函数之外,并且在调用 webhook 时不会运行,因此会有一个打开的事务。

@webhook.route('/order/insert', methods=['POST'])
def insert_orders():
    soda_json = request.json
    db.session.add(Order(
        order_id=soda_json['id'],  
        created_at=datetime.datetime.now(),
        currency=soda_json['currency'],
        total_line_items_price=soda_json['total_line_items_price'],
        refunds=sum(float(i) for i in soda_json['refunds'] if soda_json['refunds']),
        shipping_lines_price=sum([float(line['price']) for line in soda_json['shipping_lines']]),
        note=soda_json['note']
    ))
    db.session.commit()
    return '200'

【讨论】:

不幸的是,这似乎没有什么区别 - 仍然从查询中获得与启动应用程序时相同数量的订单。 hmm 你确定添加后可以在数据库中看到新记录吗?您可以添加多个新记录并在那里查看它们吗?关闭 API 后还能看到数据库中的记录吗? 仔细观察,这种行为似乎更奇怪:1. 启动应用程序 2. 检查查询,50 行 3. 检查 MySQL,50 行 4. 触发 Webhook,我的应用程序 200 OK 5. 检查 MySQL , 51 Rows 6. Check Query, 51 Rows 7. Trigger Webhook, 200 OK from my app 8. Check MySQL, 52 Rows 9. Check Query, 51 Rows 所以看起来它实际上是在显示 first仅插入我的会话中。 当你关闭 API 时,是 51 行还是 50 行呢?数据如何仅显示输入的最新值?因为我想知道提交是否正确发生。当我复制 webhook 代码时,我看到提交在 webhook 函数之外 "...我想知道提交是否正确。当我复制 webhook 代码时,我看到提交在 webhook 函数之外"【参考方案2】:

看起来查询中方法的顺序可能是个问题。

from my_app.models import Order

order_test = Order.query.all()

这就是教程中的结构 (https://pythonhosted.org/Flask-SQLAlchemy/queries.html#querying-records),但看起来这可能只是查看原始导入模型中的数据。请随时纠正我。

在烧瓶外壳中的类似操作中,我已经成功地在使用此查询结构提交后立即获取实时数据:

db.session.query([model]).all()

因此,API 方法的工作示例可能是:

@api.route('/display', methods=['POST', 'GET'])
def display_test():
    order_test = db.session.query(Order).all()
    return jsonify(json_list=[i.serialize for i in order_test]), '200'

【讨论】:

做到了!现在我的应用程序正在获取最新数据。谢谢!

以上是关于Flask-Sqlalchemy:数据库查询不返回新数据的主要内容,如果未能解决你的问题,请参考以下文章

Flask 学习-85.Flask-SQLAlchemy 多个不确定条件查询

Flask 学习-95.Flask-SQLAlchemy 查询今天当天的数据

不区分大小写的数组查询Flask-SQLAlchemy

Flask 学习-98.Flask-SQLAlchemy limit() 限制返回条数

试图在 Flask-SQLAlchemy 中使查询不区分大小写 [重复]

flask-SQLAlchemy怎么查询具体字段