迭代特定列的表列表

时间:2015-02-10 13:28:26

标签: python sqlalchemy pyramid

我有一个表列表,我想迭代并根据外键列查找特定行,然后将其删除。

这就是我的表格列表:

subrep_tables = [   TCableResistance.__table__,
                    TCapacitorBankTest.__table__,
                    TCapAndDf.__table__,
                    TMeasuredData.__table__,
                    TMultiDeviceData.__table__,
                    TStepVoltage.__table__,
                    TTemperatureData.__table__,
                    TTransformerResistance.__table__,
                    TTransformerTurnsRatio.__table__,
                    TTripUnit.__table__,
                    TVectorDiagram.__table__,
                    TWithstandTest.__table__,
                ]

我调用了列表subrep_tables,因为所有这些表都包含一个名为ixSubReport的外键。

我尝试做的是迭代列表并查找具有特定sub report的所有行并删除这些行而不是转到每个表并运行查询以删除它们(非常繁琐) )

这是我到目前为止所提出的。

for report in DBSession.query(TReport).filter(TReport.ixDevice == device_id).all():
    for sub_report in DBSession.query(TSubReport).filter(TSubReport.ixReport == report.ixReport).all():
        for table in subrep_tables:
            for item in DBSession.query(table).filter(table.ixSubReport == sub_report.ixSubReport).all():
                print "item: " + str(item)
                #DBSession.delete(item)

我在访问table的{​​{1}}条ixSubReport列时遇到了一些问题。我现在的代码给了我一个错误说:'表'对象没有属性' ixSubReport'。

如何访问我的迭代表的WHERE列以在我的WHERE子句中使用以查找特定行,以便删除它?

2 个答案:

答案 0 :(得分:4)

如果您确实要查询表格,则列位于c属性下,请使用table.c.ixSubReport

没有理由创建__table__属性的列表,只是直接查询模型。此外,您可以通过不执行前两个查询来避免大量开销;您可以在每个模型的单个查询中完成所有这些操作。 (此示例假设te模型之间存在关系)。

from sqlalchemy.orm import contains_eager

has_subrep_models = [TCableResistance, TCapacitorBankTest, ...]
# assuming each has_subrep model has a relationship "subrep"
# assuming TSubReport has a relationship "report"

for has_subrep_model in has_subrep_models:
    for item in DBSession.query(has_subrep_model).join(has_subrep_model.subrep, TSubReport.report).filter(TReport.ixDevice == device_id).options(contains_eager(has_subrep_model.subrep), contains_eager(TSubReport.report)):
        DBSession.delete(item)

当查询具有子报告的每个模型时,这只是加入相关的子报告和报告,并在那里对报告的设备进行过滤。因此,您最终会为每个模型执行一次查询,而不是1 + <num reports> + (<num reports> * <num models with sub reports>) = a lot

答案 1 :(得分:0)

感谢Denis的投入,我最终得到了这个:

for report in DBSession.query(TReport).filter(TReport.ixDevice == device_id).all():
    for sub_report in DBSession.query(TSubReport).filter(TSubReport.ixReport == report.ixReport).all():
        for table in subrep_tables:
            for item in DBSession.query(table).filter(table.c.ixSubreport == sub_report.ixSubReport).all():
                DBSession.delete(item)