2015-02-10 106 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