【问题标题】: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,如果是,则这是一个违反唯一约束的错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-21
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多