You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flask中执行自定义原生SQL遇问题,求解决方案

解决Flask-SQLAlchemy执行原生SQL的问题

我来帮你梳理下代码里的问题,然后给出可行的修正方案:

首先,你的代码里有几个容易踩坑的点:

  • 表名的引号错误:SQL里直接用单引号包裹表名'post'是不符合规范的(除非你的表名包含特殊字符),应该去掉单引号,或者用反引号(针对MySQL)来转义。
  • 返回结果未处理db.engine.execute()返回的是SQLAlchemy的ResultProxy对象,不是直接可用的列表或字典,直接赋值给self.hotness的话,后续使用会出现问题。
  • execution_options的必要性:对于查询语句来说,autocommit=True其实不是必须的,反而可能带来不必要的副作用。

修正后的代码示例

from sqlalchemy import text

# 假设这是你的类方法
def fetch_hot_posts(self):
    # 修正表名格式,编写正确的SQL语句
    sql_query = text("SELECT *, (upvotes - downvotes) * age / importance * -1 AS hotness FROM post ORDER BY hotness DESC LIMIT 50")
    # 执行查询
    result_proxy = db.engine.execute(sql_query)
    # 将结果转换为字典列表,方便后续业务逻辑使用
    self.hotness = [dict(row) for row in result_proxy]
    return self.hotness

进阶优化建议

如果你更想贴合Flask-SQLAlchemy的会话管理模式,可以用会话来执行查询,而不是直接调用engine:

from sqlalchemy import text

def fetch_hot_posts(self):
    sql_query = text("SELECT *, (upvotes - downvotes) * age / importance * -1 AS hotness FROM post ORDER BY hotness DESC LIMIT 50")
    # 使用db.session执行,利用框架的会话管理
    result = db.session.execute(sql_query)
    # 这里用row._mapping来获取字典格式的行数据
    self.hotness = [dict(row._mapping) for row in result]
    return self.hotness

另外还要注意几个细节:

  • 如果importance字段可能为0,一定要处理除以0的情况,不然会触发数据库错误,可以改成:
    SELECT *, (upvotes - downvotes) * age / NULLIF(importance, 0) * -1 AS hotness FROM post ORDER BY hotness DESC LIMIT 50
    
    NULLIF(importance, 0)会在importance为0时返回NULL,避免除法报错。
  • 确保upvotesdownvotesageimportance这些字段都是数值类型(比如INT、FLOAT),否则计算会出问题。

内容的提问来源于stack exchange,提问作者ModoUnreal

火山引擎 最新活动