我正在使用SQLAlchemy + Pyramid来操作我的数据库。但是,有一些可选表格并不总是存在于DB中。因此,在查询它们时,我尝试使用NoSuchTableError
try:
x = session.query(ABC.name.label('sig_name'),func.count('*').label('count_')).join(DEF).join(MNO).filter(MNO.relevance >= relevance_threshold).group_by(DEF.signature).order_by(desc('count_')).all()[:val]
except NoSuchTableError:
x = [-1,]
但是在执行此语句时,我得到了一个ProgrammingError
ProgrammingError: (ProgrammingError) (1146, "Table 'db.mno' doesn't exist")
为什么SQLAlchemy会引发更一般的ProgrammingError而不是更具体的NoSuchTableError?如果这确实是预期的行为,我如何确保应用程序显示正确的信息,具体取决于表格是否存在?
EDIT1
由于这是我的webapp的一部分,因此DB的模型位于models.py
(在我的金字塔webapp下)。我的.ini文件中有一个设置,要求用户选择是否有其他表可用。但不信任用户,我希望能够检查自己(在视图中)表是否存在。有争议的表类似于(在models.py
)
class MNO(Base):
__tablename__="mno"
id=Column(Integer,primary_key=True,autoincrement=True)
sid=Column(Integer)
cid=Column(mysql.MSInteger(unsigned=True))
affectability=Column(Integer)
cvss_base=Column(Float)
relevance=Column(Float)
__table_args__=(ForeignKeyConstraint(['sid','cid',],['def.sid','def.cid',]),UniqueConstraint('sid','cid'),)
如何以及在何处进行检查以便可以设置变量(最好在应用程序设置期间),告诉我表格是否存在?
注意:在这种情况下,我将不得不尝试...而不是“请求原谅”
答案 0 :(得分:6)
根据sqlalchemy文档,只有在“SQLAlchemy [is]要求从数据库加载表的定义但该表不存在时才会抛出NoSuchTableError
。”您可以尝试加载表的定义,捕获错误,然后执行查询。
如果你想通过“请求原谅”来做事:
try:
table = Table(table_name, MetaData(engine))
except NoSuchTableError:
pass
或者,您可以检查表是否存在:
修改强>
更好的是,为什么不使用has_table method:
if engine.dialect.has_table(connection, table_name):
#do your crazy query
为什么不首先使用Inspector来获取表名?
也许是这样的:
from sqlalchemy import create_engine
from sqlalchemy.engine import reflection
#whatever code you already have
engine = create_engine('...')
insp = reflection.Inspector.from_engine(engine)
table_name = 'foo'
table_names = insp.get_table_names()
if table_name in table_names:
x = session.query(ABC.name.label('sig_name'),func.count('*').label('count_')).join(DEF).join(MNO).filter(MNO.relevance >= relevance_threshold).group_by(DEF.signature).order_by(desc('count_')).all()[:val]