Exception SQLAlchemy错误处理-如何完成?

Exception SQLAlchemy错误处理-如何完成?,exception,sqlalchemy,Exception,Sqlalchemy,我想处理主键或唯一键冲突的情况,也称为重复条目。为此,我捕获了IntegrityError,它捕获的错误非常好。问题是,我似乎找不到任何简单的错误消息或错误代码来检查。我得到的只是IntegrityError.message属性,它是一个如下所示的字符串: (IntegrityError)(1062,“键“name”的重复输入“foobar”) 那不是很有帮助。使用它,我必须开始解析错误消息的代码和消息。对异常调用dir仅显示以下属性: “args”、“连接无效”、“实例”、“消息”、“源”、“

我想处理主键或唯一键冲突的情况,也称为重复条目。为此,我捕获了
IntegrityError
,它捕获的错误非常好。问题是,我似乎找不到任何简单的错误消息或错误代码来检查。我得到的只是
IntegrityError.message
属性,它是一个如下所示的字符串:

(IntegrityError)(1062,“键“name”的重复输入“foobar”)

那不是很有帮助。使用它,我必须开始解析错误消息的代码和消息。对异常调用
dir
仅显示以下属性:

“args”、“连接无效”、“实例”、“消息”、“源”、“参数”、“语句”

args
只是一个包含上述字符串的单项元组,
params
是我试图插入的数据。我似乎找不到任何方法来确定这实际上是一个重复的键错误,而不必开始使用regex或其他东西解析错误消息


有人能解释一下这个问题吗?

我在写这个问题时,通过更仔细地阅读文档,发现了这个问题。尽管如此,我还是要发布这篇文章,因为它可能会对某些人有所帮助

在SQLAlchemy的文档中,它解释了异常仅仅是底层数据库API错误的包装,并且原始错误在异常中保存为
orig
。果然,调用
e.orig.args
会得到一个组织良好的元组:

(1062,“键“名称”的重复输入“foobar”)


据我所知,唯一的方法是解析异常中的错误字符串。我找不到任何元组分别指定错误、违反唯一性约束的列和值

具体来说,可以使用子字符串搜索运算符或正则表达式搜索异常消息。例如:

    db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user))
    try:
        db.session.commit()
    except IntegrityError as err:
        db.session.rollback()
        if "UNIQUE constraint failed: user.username" in str(err):
            return False, "error, username already exists (%s)" % username
        elif "FOREIGN KEY constraint failed" in str(err):
            return False, "supplier does not exist"
        else:
            return False, "unknown error adding user"
(sqlite3.IntegrityError) UNIQUE constraint failed: user.username [SQL: 'INSERT INTO user (username, password_hash, created_time, creator_id, role, is_active, supplier_id) VALUES (?, ?, ?, ?, ?, ?, ?)'] [parameters: ('bob', ...
    except IntegrityError as err:
        db.session.rollback()
        if re.match("(.*)Duplicate entry(.*)for key 'username'(.*)", err.args[0]):
    .... etc .... 
但是,由于包含SQL语句,这些字符串可能相当长,例如:

    db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user))
    try:
        db.session.commit()
    except IntegrityError as err:
        db.session.rollback()
        if "UNIQUE constraint failed: user.username" in str(err):
            return False, "error, username already exists (%s)" % username
        elif "FOREIGN KEY constraint failed" in str(err):
            return False, "supplier does not exist"
        else:
            return False, "unknown error adding user"
(sqlite3.IntegrityError) UNIQUE constraint failed: user.username [SQL: 'INSERT INTO user (username, password_hash, created_time, creator_id, role, is_active, supplier_id) VALUES (?, ?, ?, ?, ?, ?, ?)'] [parameters: ('bob', ...
    except IntegrityError as err:
        db.session.rollback()
        if re.match("(.*)Duplicate entry(.*)for key 'username'(.*)", err.args[0]):
    .... etc .... 
因此,如果在没有sqlalchemy添加的信息的情况下搜索数据库错误消息,则可以最大限度地减少解析异常时的错误处理延迟。这可以通过检查err.args来完成,err.args应该更小:

'(sqlite3.IntegrityError) UNIQUE constraint failed: supplier_user.username',)
更新后的示例:

    db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user))
    try:
        db.session.commit()
    except IntegrityError as err:
        db.session.rollback()
        err_msg = err.args[0]
        if "UNIQUE constraint failed: supplier_user.username" in err_msg:
            return False, "error, supplier username already exists (%s)" % username
        elif "FOREIGN KEY constraint failed" in err_msg:
            return False, "supplier does not exist"
        else:
            return False, "unknown error adding user"
请注意,我在这里使用的错误语法是针对sqlite3的。正在分析mysql异常错误消息,如:

(1062, "Duplicate entry 'usr544' for key 'username'")
可以使用适当的正则表达式来完成。注意,它看起来像一个元组,但实际上是一个字符串(sqlalchemy版本1.1.3和mysql 5.5)

例如:

    db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user))
    try:
        db.session.commit()
    except IntegrityError as err:
        db.session.rollback()
        if "UNIQUE constraint failed: user.username" in str(err):
            return False, "error, username already exists (%s)" % username
        elif "FOREIGN KEY constraint failed" in str(err):
            return False, "supplier does not exist"
        else:
            return False, "unknown error adding user"
(sqlite3.IntegrityError) UNIQUE constraint failed: user.username [SQL: 'INSERT INTO user (username, password_hash, created_time, creator_id, role, is_active, supplier_id) VALUES (?, ?, ?, ?, ?, ?, ?)'] [parameters: ('bob', ...
    except IntegrityError as err:
        db.session.rollback()
        if re.match("(.*)Duplicate entry(.*)for key 'username'(.*)", err.args[0]):
    .... etc .... 

是的,这很有帮助。谢谢你为我节省时间去挖掘它。对于使用psycopg2的人:你可以使用
e.orig.pgcode
并将其映射到以获得可读代码,看起来像
e.orig.pgcode==FOREIGN\u KEY\u违规