迭代特定列的表列表

Iterate List of tables for specific column

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

这是我的 table 列表的样子:

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,因为所有这些 table 都包含一个名为 ixSubReport 的外键。

我想要做的是迭代列表并找到所有具有特定 sub report 的行并删除这些行而不是去每个 table 和 运行删除它们的查询(非常乏味)

这是我到目前为止的想法。

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)

我在为我的 WHERE 子句访问 tableixSubReport 列时遇到一些困难。我现在的代码给我一个错误提示:'Table' 对象没有属性 'ixSubReport'。

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

感谢 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)

如果你真的想查询表,列在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.