[英]Multiple left join and left join against the same model raw query convert to Django ORM
使用Django 1.11
我有以下型號:
class Vendor(Model):
class Product(Model):
class Pricebook(Model):
class Quote(Model):
vendor = models.ForeignKey(Vendor)
class SKU(Model):
product = models.ForeignKey(Product)
pricebook = models.ForeignKey(Pricebook)
vendor = models.ForeignKey(Vendor)
class SKUPrice(Model):
sku = models.ForeignKey(SKU, related_name="prices")
class LineItem(Model):
quote = models.ForeignKey(Quote, related_name="quote_line_items")
sku = models.ForeignKey(SKU)
這是適合我的原始查詢。
SELECT
qli.quantity,
sku_source.product_id,
sku_dest.id as sku_dest_id,
sku_dest_price.id as sku_dest_price_id
FROM lineitem qli
INNER JOIN sku sku_source ON
qli.sku_id = sku_source.id
LEFT JOIN sku sku_dest ON
sku_dest.pricebook_id = sku_source.pricebook_id AND
sku_dest.product_id = sku_source.product_id
LEFT JOIN skuprice sku_dest_price ON
sku_dest_price.status = 'default' AND
sku_dest_price.sku_id = sku_dest.id
WHERE qli.quotation_id = 40 AND
qli.quantity > 0 AND
sku_dest.vendor_id = 38;
我試過的是:
(the_quote_with_id_as_40
.quotation_line_items
.filter(quantity__gt=0)
.select_related('sku__product')
.values('sku__product__id', 'quantity')
)
這會產生此查詢
SELECT "sku"."product_id", "lineitem"."quantity"
FROM "lineitem"
INNER JOIN "sku" ON ("lineitem"."sku_id" = "sku"."id")
WHERE ("lineitem"."quotation_id" = 40 AND
"lineitem"."quantity" > 0)
這不完全是我想要的。
我當然可以使用原始查詢。 但我想知道是否可以使用ORM。 至少,這是為了擴展我的知識。
謝謝。
UPDATE
由於有要求澄清我的模型,我寫的是以下內容。
我有一個Quote對象。 它允許許多LineItem對象。 每個LineItem都是SKU和Quote的一對多。
SKU屬於Pricebook,產品和供應商。 這些關系的描述也可以從上面的代碼中獲得。
但為了清楚起見,我將在此重復一遍。
這種安排使得不同供應商可以銷售單個相同的產品,但它們將顯示為不同的SKU。
這是設計的。
我們的用例是這樣的:用戶試圖將特定Quote的LineItem復制到不同的Quote。
在用戶的心目中,他們並不具備理解SKU,LineItem或產品之間差異的復雜性。
這都是他們心目中的產品。 他們只是希望相同的產品出現在具有相同數量的不同報價中。
挑戰是這樣的。 我們現在有兩個行情(要復制的來源報價和要復制的目的地報價)。 兩個行情可能都有相同的供應商。 或者他們可能沒有。 用戶希望我的Django應用程序能夠自動滿足這兩種情況。
所以這意味着我需要在復制之前找出以下內容。
原始查詢允許我在單個查詢中提取所有4條信息。 這很有效率。
因此,您看到我有別名sku_source
和sku_dest
這就是我的WHERE標准包含3個條件的原因:
有可能:
同一產品(vis-a-vis SKU)的多個LineItem將出現在同一個源Quote中。
目標供應商(即目的地報價的供應商)不銷售源供應商確實銷售的特定產品。 因此我使用LEFT JOIN。 這意味着此特定產品不會重復。
我希望這可以解決問題。
對我來說,你解決問題的方式是不正確的。
您仍在嘗試解釋查詢,而不是您需要的對象。 使用ORM時,您需要停止考慮查詢,並開始考慮對象以及它們如何相互進行/交互。 通過這樣做,您將把業務邏輯放在代碼(模型,管理器等)中而不是在查詢中。 您不希望在查詢中包含業務邏輯,然后開始思考,確定如何立即創建此查詢? 具有啞查詢的智能對象更容易被其他人優化和理解,而不是具有啞代碼(對象)的智能查詢。
從對象開始,編寫代碼,然后對其進行優化。
如果你向我展示一個未優化的面向對象版本的方法/你需要什么來制作這些副本,我可能會告訴你如何優化它。
在那之前,並不是完全偏離主題,嘗試這個查詢,但我不能保證你正在尋找的東西:
quote.quotation_line_items.filter(
quantity__gt=0,
sku__vendor__sku__vendor=38,
sku__vendor__sku__product=models.F('sku__product'),
sku__vendor__sku__pricebook=models.F('sku__pricebook'),
).values(
'quantity',
'sku__product_id', # sku source product_id
'sku__vendor__sku__id', # sku dest id
'sku__vendor__sku__skuprice__id' # sku dest skuprice id
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.