【问题标题】:No exception raised in SqlAlchemy if error in Vertica database如果 Vertica 数据库出错,SqlAlchemy 不会引发异常
【发布时间】:2023-01-29 01:51:16
【问题描述】:
我在 Vertica 中定义了表,其中一列强制执行了 UNIQUE 约束。现在,在插入新行时,如果列中存在相同的值,则在数据库 shell 中执行查询时会引发 error 6745。我正在尝试使用 Sqlalchemy 来实现这一点。
我定义了一个 Sqlalchemy 引擎并使用它连接到数据库。接下来我使用execute(),它可以与上面创建的连接一起使用来执行原始 SQL 查询。我在上述实现周围使用 try-except 块来捕获任何异常。使用 Sqlalchemy 插入新行时不会引发异常,但会在数据库端强制执行约束(不会写入重复的条目)。但是数据库中引发的错误并没有被 Sqlalchemy 捕获,因此无法真正判断操作是否成功或者是否与添加的新数据发生冲突。
如果数据库出现错误,我如何配置 Sqlalchemy 以引发异常?
我正在使用 vertica_python 方言。
临时解决方案:
目前,我使用执行操作前后表中的条目数来对操作状态进行分类。这是一个肮脏的 hack,效率不高。
【问题讨论】:
标签:
python
python-3.x
sqlalchemy
flask-sqlalchemy
vertica
【解决方案1】:
您可以通过将 Vertica 连接对象上的 raise_on_unique_violation 标志设置为 True,将 SqlAlchemy 配置为引发异常。此标志告诉 SqlAlchemy 在发生唯一约束违规时引发异常,而不是默默地忽略它。
例如:
from sqlalchemy import create_engine
from sqlalchemy.dialects.vertica import VerticaDialect
engine = create_engine("vertica+vertica_python://username:password@hostname:port/dbname",
connect_args={'raise_on_unique_violation': True},
echo=True,
dialect_cls=VerticaDialect)
connection = engine.connect()
当您使用 connection.execute() 方法插入新行时,如果发生唯一约束冲突,SqlAlchemy 将引发 UniqueViolation 异常,您可以在代码中捕获和处理该异常。
您还可以使用 session.flush() 和 session.commit() 来处理异常。
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
try:
session.add(new_row)
session.flush()
session.commit()
except IntegrityError as e:
session.rollback()
raise e
您可以检查错误代码是否为 6745,如果是,则这是一个违反唯一约束的错误。