Django prefetch_related 多个查询
Django prefetch_related multiple queries
我正在使用 prefetch_related 来连接三个表。 产品, ProductPrices 和 ProductMeta。但是除了我正在关注文档之外,调试器还说我正在使用 三个查询 而不是一个(带连接)
这也造成了第二个问题。 某些产品在某些国家/地区没有价格,因为它们在那里不可用。但是使用此代码,产品出现但价格为空。
因此,我想排除没有价格或元数据的产品。我做错了什么?
这是我的代码:
prefetch_prices = Prefetch(
'product_prices',
queryset=ProductPrices.objects.filter(country=country_obj),
to_attr='price_info'
)
prefetch = Prefetch(
'product_meta',
queryset=ProductMeta.objects.filter(language=lang),
to_attr='meta_info'
)
products = Product.objects.prefetch_related(prefetch, prefetch_prices).all()
产生这些 SQL 查询:
{ 'sql': 'SELECT DISTINCT `products`.`id`, `products`.`image`, '
'`products`.`wholesale_price`, `products`.`reference`, '
'`products`.`ean13`, `products`.`rating`, `products`.`sales`, '
'`products`.`active`, `products`.`active_in`, '
'`products`.`encilleria`, `products`.`delivery`, '
'`products`.`stock`, `products`.`ingredients`, '
'FROM `products` WHERE `products`.`active` = 1 ',
'time': '0.098'},
{ 'sql': 'SELECT `products_meta`.`id`, `products_meta`.`product_id`, '
'`products_meta`.`name`, `products_meta`.`slug`, '
'`products_meta`.`tagline`, `products_meta`.`key_ingredients`, '
'`products_meta`.`ideal_for`, `products_meta`.`description`, '
'`products_meta`.`advice`, `products_meta`.`summary`, '
'`products_meta`.`language` FROM `products_meta` WHERE '
"(`products_meta`.`language` = 'en' AND "
'`products_meta`.`product_id` IN (52001, 51972, 52038, 52039, '
'52040, 52041, 51947, 51948, 51949, 51950, 51951, 51953, 51954, '
'51832))',
'time': '0.096'},
{ 'sql': 'SELECT `products_prices`.`id`, `products_prices`.`product_id`, '
'`products_prices`.`country_id`, `products_prices`.`price` FROM '
'`products_prices` WHERE (`products_prices`.`country_id` = 1 '
'AND `products_prices`.`product_id` IN (52001, 51972, 52038, '
'52039, 52040, 52041, 51947, 51948, 51949, 51950, 51951, 51953, '
'51954, 51832))',
'time': '0.046'}
谢谢
来自 prefetch_related
文档
Returns a QuerySet that will automatically retrieve, in a single
batch, related objects for each of the specified lookups.
从下面的解释可以看出
prefetch_related
, on the other hand, does a separate lookup for each
relationship, and does the ‘joining’ in Python.
prefetch_related
将查询每个表并将它们合并到 python
此外,如果您有外键而不是多对多,您可以使用 select_related
代替
正如@iklinac 所说,prefetch_related
将执行多个查询并合并结果。
但是如果你想“排除空行”或类似 INNER JOIN 的功能,你可以这样做:
a = ProductPrices.objects.filter(country=country_obj)
prefetch1 = Prefetch(
'product_prices',
queryset=a,
to_attr='price_info'
)
b = ProductMeta.objects.filter(language=lang)
prefetch2 = Prefetch(
'product_meta',
queryset=b,
to_attr='meta_info'
)
products = products.prefetch_related(prefetch1, prefetch2)
products = products.filter(id__in=a.values_list('product_id'))
products = products.filter(id__in=b.values_list('product_id'))
我正在使用 prefetch_related 来连接三个表。 产品, ProductPrices 和 ProductMeta。但是除了我正在关注文档之外,调试器还说我正在使用 三个查询 而不是一个(带连接)
这也造成了第二个问题。 某些产品在某些国家/地区没有价格,因为它们在那里不可用。但是使用此代码,产品出现但价格为空。
因此,我想排除没有价格或元数据的产品。我做错了什么?
这是我的代码:
prefetch_prices = Prefetch(
'product_prices',
queryset=ProductPrices.objects.filter(country=country_obj),
to_attr='price_info'
)
prefetch = Prefetch(
'product_meta',
queryset=ProductMeta.objects.filter(language=lang),
to_attr='meta_info'
)
products = Product.objects.prefetch_related(prefetch, prefetch_prices).all()
产生这些 SQL 查询:
{ 'sql': 'SELECT DISTINCT `products`.`id`, `products`.`image`, '
'`products`.`wholesale_price`, `products`.`reference`, '
'`products`.`ean13`, `products`.`rating`, `products`.`sales`, '
'`products`.`active`, `products`.`active_in`, '
'`products`.`encilleria`, `products`.`delivery`, '
'`products`.`stock`, `products`.`ingredients`, '
'FROM `products` WHERE `products`.`active` = 1 ',
'time': '0.098'},
{ 'sql': 'SELECT `products_meta`.`id`, `products_meta`.`product_id`, '
'`products_meta`.`name`, `products_meta`.`slug`, '
'`products_meta`.`tagline`, `products_meta`.`key_ingredients`, '
'`products_meta`.`ideal_for`, `products_meta`.`description`, '
'`products_meta`.`advice`, `products_meta`.`summary`, '
'`products_meta`.`language` FROM `products_meta` WHERE '
"(`products_meta`.`language` = 'en' AND "
'`products_meta`.`product_id` IN (52001, 51972, 52038, 52039, '
'52040, 52041, 51947, 51948, 51949, 51950, 51951, 51953, 51954, '
'51832))',
'time': '0.096'},
{ 'sql': 'SELECT `products_prices`.`id`, `products_prices`.`product_id`, '
'`products_prices`.`country_id`, `products_prices`.`price` FROM '
'`products_prices` WHERE (`products_prices`.`country_id` = 1 '
'AND `products_prices`.`product_id` IN (52001, 51972, 52038, '
'52039, 52040, 52041, 51947, 51948, 51949, 51950, 51951, 51953, '
'51954, 51832))',
'time': '0.046'}
谢谢
来自 prefetch_related
文档
Returns a QuerySet that will automatically retrieve, in a single batch, related objects for each of the specified lookups.
从下面的解释可以看出
prefetch_related
, on the other hand, does a separate lookup for each relationship, and does the ‘joining’ in Python.
prefetch_related
将查询每个表并将它们合并到 python
此外,如果您有外键而不是多对多,您可以使用 select_related
代替
正如@iklinac 所说,prefetch_related
将执行多个查询并合并结果。
但是如果你想“排除空行”或类似 INNER JOIN 的功能,你可以这样做:
a = ProductPrices.objects.filter(country=country_obj)
prefetch1 = Prefetch(
'product_prices',
queryset=a,
to_attr='price_info'
)
b = ProductMeta.objects.filter(language=lang)
prefetch2 = Prefetch(
'product_meta',
queryset=b,
to_attr='meta_info'
)
products = products.prefetch_related(prefetch1, prefetch2)
products = products.filter(id__in=a.values_list('product_id'))
products = products.filter(id__in=b.values_list('product_id'))