如何返回 Flask-SqlAlchemy 错误详细信息

Posted

技术标签:

【中文标题】如何返回 Flask-SqlAlchemy 错误详细信息【英文标题】:How to return Flask-SqlAlchemy error details 【发布时间】:2019-10-12 07:54:08 【问题描述】:

我正在使用Flask 1.0、Flask-SqlAlchemy 2 和Angular 7。

当 SqlAlchemy 抛出错误时,我想在前端显示定制的错误消息。

official Flask documentation 中有一个关于如何处理错误的部分,还有一个关于 SO 的similar question,尽管它与Flask-Restless 有关。但我无法将这些点联系起来。

当 SqlAlchemy 抛出错误时,它看起来像这样:

DETAIL:  Key (id)=(123) is not present in table "foo".

我将错误返回给路由:

try:
    db.session.commit()
except Exception as error:
    db.session.flush()
    db.session.rollback()
    return error

在路线中我正在检查是否有错误:

if status == True:
    return jsonify(  "success": True  ), 201
else:
    return error_response(500, str(status))

我的 error_response 类看起来像这样:

def error_response(status_code, message=None):
    payload = "error": HTTP_STATUS_CODES.get(status_code, "Unknown error")
    if message:
        payload["message"] = message
        response = jsonify(payload)
        response.status_code = status_code
    return response

但响应 json 仅包含一般错误消息:

"message": "Http failure response for http://127.0.0.1:5000/database/add_foo: 0 Unknown Error"

【问题讨论】:

【参考方案1】:

您可以阅读error 对象并从中创建您自己的自定义消息。有关所有详细信息,请尝试在控制台中打印 error.\__dict__

例如:

from sqlalchemy import create_engine
from sqlalchemy import MetaData
from sqlalchemy import Table
from sqlalchemy import Column
from sqlalchemy import Integer, String

db_uri = 'sqlite:///'
engine = create_engine(db_uri)
conn = engine.connect()

# Create a metadata instance
meta = MetaData(engine)
table = Table('user', meta,
   Column('id', Integer, primary_key=True),
   Column('l_name', String),
   Column('f_name', String))
meta.create_all()
# Insert Data
conn.execute(table.insert(),[
   'id':1,'l_name':'Hi','f_name':'bob',
   'id':2,'l_name':'Hello','f_name':'john',
   'id':3,'l_name':'yo','f_name':'bob-john'])

result =conn.execute("SELECT * FROM user")
for res in result:
  print(res)
# Intensionally violating unique constraint
try:
  ins = table.insert().values(
      id=3,
      l_name='Hello',
      f_name='World')
# conn = engine.connect()
  conn.execute(ins)
except Exception as error:
  print(str(error.orig) + " for parameters" + str(error.params))

输出将是:-

【讨论】:

非常感谢您的帮助。我花了一段时间才弄清楚为什么您的解决方案对我不起作用(见下文)。无论如何,我相信它对其他读者有帮助,所以真的很感激!【参考方案2】:

结果当我尝试进行批量保存时返回了错误:

db.session.bulk_save_objects(companies_to_add, return_defaults = True)

我的印象是在执行任一操作时都会引发错误

db.session.commit()

db.session.flush()

显然我错了。我现在将批量保存放在 try 块中:

try:
    db.session.bulk_save_objects(companies_to_add, return_defaults = True)
except Exception as error:
    db.session.rollback()
    return error

现在我可以在前端捕获错误了。

【讨论】:

以上是关于如何返回 Flask-SqlAlchemy 错误详细信息的主要内容,如果未能解决你的问题,请参考以下文章

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

flask-sqlalchemy 外连接的 Flask-marshmallow 转储返回空

Flask-SQLAlchemy 错误 MySQL 服务器已消失

Flask-SQLAlchemy错误

使用 mysql 和烧瓶登录的 Flask-sqlalchemy 损坏管道错误 32

错误flask-sqlalchemy NameError:未定义全局名称'joinedload'