[英]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.