2013-03-14 100 views
0

所以,我寫了一個非常複雜的查詢,它從兩個表中提取並連接一堆數據。如何使用SQLAlchemy的表達式語言編寫條件語句?

SELECT 
    /* Common attributes */ 
    carrier.name, 
    carrier.notes, 
    carrier.turnaround, 

    /* Either per-reseller price, generic reseller price or default price */ 
    IFNULL(
     rsu.price, 
     IF(
      (
       carrier.reseller_price != IS NOT NULL AND 
       carrier.reseller_price != 0 
      ), 
      carrier.reseller_price, 
      carrier.price 
     ) 
    ) AS price, 
    IFNULL(
     rsu.price_barred, 
     IF(
      (
       carrier.reseller_price_barred IS NOT NULL AND 
       carrier.reseller_price_barred != 0 
      ), 
      carrier.reseller_price_barred, 
      carrier.price_barred 
     ) 
    ) AS price_barred 
FROM 
    `core_carrier` AS carrier 
LEFT OUTER JOIN 
    `core_resellerunlock` AS rsu ON (
     rsu.carrier_id = carrier.id AND 
     rsu.reseller_id = 1 
    ) 

有人建議重寫這個使用SQLAlchemy的查詢生成器的方法嗎?我不確定這些條款是否有可能。我不想這樣做使用ORM(據我所知,使用SQLAlchemy ORM純粹不可能執行此操作)。我只是尋找一種或多或少的使用SQLAlchemy核心的可移植方式。

+0

發佈模型將會有所幫助。 – CppLearner 2013-03-15 00:13:02

+0

有沒有型號。你的意思是數據庫模式? – 2013-03-15 19:40:42

+0

SQLAlchemy的最佳特性是它的ORM特性。當我說模型時,我正在談論ORM。架構是好的,但我希望你沒有定義一個原始架構。我的意思是你甚至可以從你的MySQL conole中複製和粘貼模式。無論採用哪種方式,使用完整的模式都可以更容易閱讀。 – CppLearner 2013-03-16 05:18:08

回答

2

您可以在查詢中使用the case function包含一個條件。這不會產生完全相同的SQL,但可以產生功能相同的東西。

這裏有一個簡單的例子,與carrierrsu變量指Table對象,case參照上述功能:

join = carrier.join(rsu, (rsu.c.carrier_id == carrier.c.id) & (rsu.c.reseller_id == 1)) 
query = join.select([ 
    carrier.c.name, 
    carrier.c.notes, 
    carrier.c.turnaround, 
    case([ 
     (
      rsu.c.price_barred == None, 
      case([ 
       (
        (carrier.c.reseller_price != None) & (carrier.c.reseller_price != 0), 
        carrier.c.reseller_price 
       ) 
      ], 
      else_=carrier.c.price 
     ) 
    ] 
]) 

您可能會發現它方便做一些輔助函數來表示你higher-級別IFNULLIF用於提高查詢的可讀性。例如:

def if_(expr, then, else_): 
    return case([ 
     (expr, then) 
    ], else_=else_)