python – 将django RawQuerySet转换为Queryset

我有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查询集?

有没有更好的方法呢?

文档:

> ArrayField https://docs.djangoproject.com/en/2.0/ref/contrib/postgres/fields/#arrayfield
> Custom Manager https://docs.djangoproject.com/en/2.0/topics/db/managers/#custom-managers-and-model-inheritance
>原始查询https://docs.djangoproject.com/en/2.0/topics/db/sql/#performing-raw-sql-queries

解决方法:

您可以使用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],
)

相关文章

项目需要,有个数据需要导入,拿到手一开始以为是mysql,结果...
本文小编为大家详细介绍“怎么查看PostgreSQL数据库中所有表...
错误现象问题原因这是在远程连接时pg_hba.conf文件没有配置正...
因本地资源有限,在公共测试环境搭建了PGsql环境,从数据库本...
wamp 环境 这个提示就是说你的版本低于10了。 先打印ph...
psycopg2.OperationalError: SSL SYSCALL error: EOF detect...