我有一个表列表,我想迭代并根据外键列查找特定行,然后将其删除。
这就是我的表格列表:
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子句中使用以查找特定行,以便删除它?
答案 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)