查询来自外部源的数据的django模型

时间:2017-01-30 23:03:35

标签: sql django postgresql django-models django-queryset

鉴于django模型...

models.py

class UserRelationship:
    user_id - IntegerField
    staff_id - IntegerField
    valid_from - DateTimeField

...以及从外部API检索数据的一些逻辑。

api.py

class Approval:
    user_id - Int
    created_at - DateTime

列出"批准":

approvals = [{'user_id': <user_id>, 'created_at': <created_at>}, ...]

我需要找到一种有效的方法来导出&#34; staff_id&#34;在批准批准&#34;批准&#34;对象。

我无法想到使用django ORM这样做的方法。

我知道我们可以使用Q对象进行复杂的查找:

from django.db.models import Q

qs = UserRelationship.obejcts.filter(Q(user_id=<user_id>) & Q(created_at__lte=<created_at>))

但仅适用于user_id/created_at的单一组合,我如何为大型列表(~20k +)批准&#34;批准&#34;。

任何帮助或提示将不胜感激。非常感谢。

1 个答案:

答案 0 :(得分:2)

  

列出&#34;批准&#34; (来自外部来源)例如

   approvals = [{'user_id': <user_id>, 'created_at': <created_at>}, ...]
     

我需要找到一种有效的方法来找到&#34; staff_id&#34;在批准~20k +&#34;批准&#34;的清单时对象。

     

即每个dict找到匹配的行

   approval.user_id = user_relationship.user_id and approval.created_at <= user_relationship.valid_from

根据您的外部数据源,索引等,效率会很重要。但是对于您如何制定查询的直接问题,best place to start is with django.db.models.Q

  

如果您需要执行更复杂的查询(例如,使用 OR 语句进行查询),则可以使用 Q 对象。< / p>      

Q 对象( django.db.models.Q )是用于封装关键字参数集合的对象。这些关键字参数在上面的“字段查找”中指定。

filters = Q()
for x in approvals:
    filters |= Q(user_id=x['user_id'], valid_from__lte=x['created_at'])
relationships = UserRelationship.objects.filter(filers)

您可以通过循环staff_id查询集来获取relationships。此示例假定您在批准列表中有唯一的user_id,以便您可以返回并将正确的批准与正确的staff_id相关联。如果批准列表中可以有相同user_id的倍数,则只需对user_id在每个分区中出现多次的方式进行分区。

partitions = []
check_ids = []
for x in approvals:
    current_partition = None
    current_check_id = None
    for partition, check_id in zip(partitions, check_ids):
        if x['user_id'] not in check_id:
            current_partition = partition
            current_check_id = check_id

    if current_partition is None:
        partitions.append(list())
        check_ids.append(set())
        current_partition = partitions[-1]
        current_check_id = check_ids[-1]
    current_check_id.add(x['user_id']
    current_partition.append(x)