2015-02-10 91 views
2

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

这是我的表的名单看起来像:

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) 

我有一些困难访问tableixSubReport列我WHERE条款。我现在的代码给了我一个错误:'表'对象没有'ixSubReport'属性。

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

+3

'table.c.ixSubReport' http://docs.sqlalchemy.org/en/rel_0_9/core/metadata.html#accessing-tables-and-columns – 2015-02-10 15:10:27

+0

另外,您的模型和列名称是不必要的冗长和令人困惑。不需要为每个模型添加前缀“T”,每个索引列中都带有“ix”等。为什么每个模型都会显示其主键“ix <表名称>”?这听起来像一个外键的名称(令人困惑的是,*是*,在相关模型上,更容易称之为“id”,您已经知道它是其中的一部分) – davidism 2015-02-10 16:42:23

+0

我有'T'作为前缀为我的模型区分它作为一个表,ix是我的'索引'的前缀,因此它更容易识别它作为标识符,有助于消除回去并检查我的字段是什么数据类型,如果我忘记了 – john 2015-02-11 19:36:04

回答

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

+0

谢谢你,看起来非常简单和干净。 – john 2015-02-10 18:53:37

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) 
+0

我会实际上使用了第二个选项,我会更正我的措辞 – john 2015-02-10 16:26:12