3

我正在使用 SQLAlchemy + Pyramid 对我的数据库进行操作。但是,有些可选表并不总是希望出现在数据库中。因此,在查询他们时,我尝试使用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?如果这确实是预期的行为,我如何确保应用程序根据表格是否存在/不存在显示正确的信息?

编辑1

由于这是我的 webapp 的一部分,因此 DB 的模型在models.py(在我的金字塔 webapp 下)。我的 .ini 文件中有一个设置,要求用户选择其他表是否可用。但不信任用户,我希望能够(在视图中)自己检查表是否存在。有争议的表格类似于 (in 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'),)

应该如何以及在哪里进行检查,以便可以设置一个变量(最好在应用程序设置期间),它告诉我表是否存在?

注意:在这种情况下,我将不得不尝试 if...else 而不是“请求原谅”

4

1 回答 1

6

根据sqlalchemy文档, aNoSuchTableError仅在“要求 SQLAlchemy [is] 从数据库加载表的定义,但该表不存在”时才抛出。您可以尝试加载表的定义,在那里捕获错误,然后执行查询。

如果你想通过“请求原谅”来做事:

try:
    table = Table(table_name, MetaData(engine)) 
except NoSuchTableError:
    pass

或者,您可以只检查表是否存在:

编辑:

更好的是,你为什么不使用has_table 方法

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]
于 2012-05-01T10:21:29.537 回答