我使用 Flask-SQLAlchemy(版本 2.5.1)和 Python 3.11 连接到 PostgreSQL 15 数据库。
我想使用 DROP TABLE IF EXISTS ... CASCADE 删除表(如果存在)。这是我的代码:
from sqlalchemy import text
from sqlalchemy.exc import SQLAlchemyError
try:
sql = text("DROP TABLE IF EXISTS {table_name} CASCADE")
db.session.execute(sql)
db.session.commit()
except Exception as e:
logger.error(f"Failed to drop {table_name} table: {str(e)}")
except SQLAlchemyError as e:
db.session.rollback()
logger.error(f"An error occurred: {str(e)}")
但是,当表不存在时,即使 PostgreSQL 日志显示以下内容,我也没有看到 Python 中引发任何异常:
LOG: statement: DROP TABLE IF EXISTS devices CASCADE
NOTICE: table "devices" does not exist, skipping
LOG: statement: COMMIT
由于该表不存在,PostgreSQL 会记录一条通知,但在我的 Python 代码中没有传播任何异常。
我的问题是:
execute()
和 commit()
命令后,我是否应该手动检查数据库中的错误代码?当表不存在时,我是否应该期望引发异常并传递“原始”SQL 语句?
IF EXISTS
,如果表不存在,PostgreSQL 将不会出错。有没有办法将数据库的状态消息绑定到我的Python代码,以便我可以更明确地处理此类情况?
NOTICE
消息,但如果不检查日志则无法直接访问它们(或者至少没有记录的方法可以执行此操作)。请参阅注意日志记录的文档。在execute()和commit()命令之后我应该手动检查数据库中的错误代码吗?
这是一个简单的例子:
import logging
import sqlalchemy as sa
logging.basicConfig()
logging.getLogger('sqlalchemy')
logging.getLogger('sqlalchemy.dialects.postgresql').setLevel(logging.INFO)
engine = sa.create_engine('postgresql+psycopg2:///so')
with engine.begin() as conn:
conn.execute(sa.text("""DROP TABLE IF EXISTS t"""))
这会产生以下输出:
INFO:sqlalchemy.engine.Engine:select pg_catalog.version()
INFO:sqlalchemy.engine.Engine:[raw sql] {}
INFO:sqlalchemy.engine.Engine:select current_schema()
INFO:sqlalchemy.engine.Engine:[raw sql] {}
INFO:sqlalchemy.engine.Engine:show standard_conforming_strings
INFO:sqlalchemy.engine.Engine:[raw sql] {}
INFO:sqlalchemy.engine.Engine:BEGIN (implicit)
INFO:sqlalchemy.engine.Engine:DROP TABLE IF EXISTS t
INFO:sqlalchemy.engine.Engine:[generated in 0.00009s] {}
INFO:sqlalchemy.dialects.postgresql:NOTICE: table "t" does not exist, skipping
INFO:sqlalchemy.engine.Engine:COMMIT