mis*_*bah 5 python django postgresql django-models django-managers
我有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()
Run Code Online (Sandbox Code Playgroud)
这有效:
qs = ModelB.objects.get_for_index(index_id=1)
Run Code Online (Sandbox Code Playgroud)
但是,如果"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)
Run Code Online (Sandbox Code Playgroud)
但这会返回一个django.db.models.query.RawQuerySet
实例.
但有了这个,我就不能做事queryset.values()
了.
如何将其转换为普通的Django查询集?
有没有更好的方法呢?
文档:
小智 12
您可以使用RawSQL表达式:
ModelB.objects.filter(id__in=RawSQL(
'SELECT unnest(a.pk_values) FROM app_modela a WHERE a.id = %s',
[index_id]
))
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用extra()重现您在问题中的确切查询:
ModelB.objects.extra(
tables=['foo_modela'],
where=[
'"app_modelb"."id" = ANY("app_modela"."pk_values")',
'"app_modela"."id" = %s',
],
params=[index_id],
)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5794 次 |
最近记录: |