gpt4 book ai didi

sqlalchemy - 如何区分 SQLAlchemy IntegrityError 的原因?

转载 作者:行者123 更新时间:2023-12-01 23:38:49 24 4
gpt4 key购买 nike

当事务存在数据完整性问题时,SQLAlchemy 似乎只是抛出一个一般的 IntegrityError。当然,异常中包含了确切的查询和错误消息,这足以供人工调试程序。但是,在为异常编写错误处理代码时,据我所知,似乎没有一个好方法来检查哪个表上的哪个约束是导致错误的原因。此外,异常是由 session.commit() 行引发的,而不是实际负责产生错误的行,因此我也无法区分使用多个 try/except block 。

除了尝试以编程方式解析错误消息和/或查询之外,有没有一种方法可以区分重复的主键错误与外键错误或失败的 CHECK 约束等等?或者甚至只是一种判断哪个表的哪一列违反了数据完整性的方法?或者只是一种在导致错误的行上立即引发异常而不是等待事务被提交的方法?

最佳答案

IntegrityError 实例具有 origstatement 属性,可以检查它们以分别获取错误消息和失败的 SQL 语句。

给定这个模型:

class Foo(Base):
__tablename__ = 'foo20201209'

id = sa.Column(sa.Integer, primary_key=True)
bar = sa.Column(sa.String(2), unique=True)
baz = sa.Column(sa.Integer, sa.CheckConstraint('baz >= 0'), default=0)

这段代码:

conn_strings = ['postgresql+psycopg2:///test',
'mysql+mysqlconnector:///test',
'sqlite://']


for cs in conn_strings:
engine = sa.create_engine(cs)
Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)

session = orm.Session(bind=engine)

for kwds in [{'bar': 'a'}, {'bar': 'a'}, {'bar': 'b', 'baz': -11}]:
session.add(Foo(**kwds))
try:
session.commit()
except sa.exc.IntegrityError as ex:
print(ex.orig)
print(ex.statement)
print()
session.rollback()
session.close()
engine.dispose()

将产生这个输出:

duplicate key value violates unique constraint "foo20201209_bar_key"
DETAIL: Key (bar)=(a) already exists.

INSERT INTO foo20201209 (bar, baz) VALUES (%(bar)s, %(baz)s) RETURNING foo20201209.id

new row for relation "foo20201209" violates check constraint "foo20201209_baz_check"
DETAIL: Failing row contains (3, b, -11).

INSERT INTO foo20201209 (bar, baz) VALUES (%(bar)s, %(baz)s) RETURNING foo20201209.id

1062 (23000): Duplicate entry 'a' for key 'bar'
INSERT INTO foo20201209 (bar, baz) VALUES (%(bar)s, %(baz)s)

4025 (23000): CONSTRAINT `foo20201209.baz` failed for `test`.`foo20201209`
INSERT INTO foo20201209 (bar, baz) VALUES (%(bar)s, %(baz)s)

UNIQUE constraint failed: foo20201209.bar
INSERT INTO foo20201209 (bar, baz) VALUES (?, ?)

CHECK constraint failed: foo20201209
INSERT INTO foo20201209 (bar, baz) VALUES (?, ?)

关于sqlalchemy - 如何区分 SQLAlchemy IntegrityError 的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65189213/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com