【问题标题】:Convert django RawQuerySet to Queryset将 django RawQuerySet 转换为 Queryset
【发布时间】:2018-01-16 18:58:32
【问题描述】:

我有 2 个 Django 模型,ModelA 和一个 ArrayField,用于存储大量主键值(可能是 50k+ 列表)

class ModelA(models.Model):
    pk_values = ArrayField(models.IntegerField())

class CustomManager(manager.Manager):

    def get_for_index(self, index_id):
        qs = self.get_queryset()
        obj = ModelA.objects.get(pk=index_id)
        return qs.filter(id__in=obj.pk_values)

class ModelB(models.Model):
    # [...] some fields

    objects = CustomManager()

这行得通:

qs = ModelB.objects.get_for_index(index_id=1)

但是,当“pk_values”是一个大列表时,这会非常慢。

所以我尝试进行原始 SQL 查询:

class CustomManager(manager.Manager):
    def get_for_index(self, index_id):
        qs = self.get_queryset()
        sql = "SELECT * FROM myapp_model_b JOIN myapp_model_a ON myapp_model_b.id = ANY(myapp_model_a.pk_values) WHERE myapp_model_a.id = '%s'" % index_id
        return qs.raw(sql)

但这会返回一个django.db.models.query.RawQuerySet 实例。

但是有了这个,我以后就不能做queryset.values()之类的事情了。

如何将其转换为普通的 Django 查询集?

有更好的方法吗?

文档:

【问题讨论】:

  • 我可能遗漏了一些东西,但你能用ManyToManyField吗?
  • 这些是现有模型..所以我不能改变它。

标签: python django postgresql django-models django-managers


【解决方案1】:

您可以使用RawSQL 表达式:

ModelB.objects.filter(id__in=RawSQL(
    'SELECT unnest(a.pk_values) FROM app_modela a WHERE a.id = %s',
    [index_id]
))

或者,您可以使用extra() 重现您在问题中的确切查询:

ModelB.objects.extra(
    tables=['foo_modela'],
    where=[
        '"app_modelb"."id" = ANY("app_modela"."pk_values")',
        '"app_modela"."id" = %s',
    ],
    params=[index_id],
)

【讨论】:

  • 我刚刚看到你的回答......在我发布了我的更新之后。非常感谢
【解决方案2】:

更新:我使用 .extra() 得到了一些工作

class CustomManager(manager.Manager):
    def get_for_index(self, index_id):
        qs = self.get_queryset()
        sql = "myapp_model_b.id IN (SELECT UNNEST(myapp_model_a.pk_values) FROM myapp_model_a WHERE myapp_model_a.id='%s')" % index_id
        return qs.extra(where=[sql])

文档:https://docs.djangoproject.com/en/2.0/ref/models/querysets/#django.db.models.query.QuerySet.extra

【讨论】:

    猜你喜欢
    • 2012-07-26
    • 2013-05-25
    • 1970-01-01
    • 2013-09-07
    • 2011-05-24
    • 2012-03-08
    • 2018-01-22
    • 2019-04-03
    • 1970-01-01
    相关资源
    最近更新 更多