【问题标题】:Perform lookup and update within a single Django query在单个 Django 查询中执行查找和更新
【发布时间】:2017-11-16 11:58:04
【问题描述】:

我有两个模型:MetaModelRelatedModel。我想在MetaModel 查询中包含RelatedModel 查找的结果,并且我想在单个数据库调用中执行此操作。

我尝试定义一个“子查询”QuerySet 以在主查询中使用,但这没有奏效 - 它仍在进行两个查询来完成操作。

注意:我不能使用传统的ForeignKey 关系,因为profile_id 字段不是唯一的。唯一性是profile_idchannel 的组合。这是一个聚合表,profile_id 不保证在多个第三方渠道中是唯一的。

有什么建议吗?

型号:

class Channel(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(
        max_length=25,
    )

class MetaModel(models.Model):
    profile_id = fields.IntegerField()
    channel = fields.ForeignKey(Channel))
    metadata = fields.TextField()

class RelatedModel(models.Model):
    related_id = fields.IntegerField()
    profile_id = fields.IntegerField()
    channel = fields.ForeignKey(Channel))

虚拟数据

channel = Channel("Web site A")
channel.save()

sample_meta = MetaModel(profile_id=1234, channel=channel)
sample_related = RelatedModel(profile_id=1234, related_id=5678, channel=channel)

查询:

# Create a queryset to filter down to the single record we need the `profile_id` for
# I've limited to the only field we need via a `values` operation 
related_qs = RelatedAccount.objects.filter(
    related_id=5678,
    channel=channel
).values_list("profile_id", flat=True)

# I'm doing an update_or_create as there is other data to store, not included for brevity
obj, created = MetaModel.objects.update_or_create(
    profile_id=related_qs.first(),  # <<< This var is the dynamic part of the query
    channel=channel,
    defaults={"metadata": "Metadata is added to a new or existing record."}
)

【问题讨论】:

    标签: python django postgresql


    【解决方案1】:

    关于您对唯一性的说明,您可以在 Django 中使用unique_together 选项,如documentation 中所述。

    class MetaModel(models.Model):
        profile_id = fields.ForeignKey(RelatedModel)
        channel = fields.ForeignKey(Channel)
        metadata = fields.TextField()
    
        class Meta:
            unique_together = ('profile_id', 'channel')
    

    然后您可以相应地更改您的查询,应该可以解决您的问题。

    【讨论】:

    • 谢谢@Borut,我不知道unique_together。不幸的是,在这种情况下它实际上并没有帮助 - 由于遗留原因,每个通道的配置文件记录存在于不同的模型和表中,因此我无法通过 ForeignKey 链接到单个模型。你激励我考虑在以后合并这些模型,现在这个unique_together/复合方法可用。
    • @PhilSheard,当你说你尝试过subquery时,你的意思是在1.11版本中引入了subquery expression吗?
    • 不,我不知道它实际上存在。我试图通过将查询集作为参数传递来推断子查询,但明确的Subquery() 可能是我所追求的。谢谢,我试试看。
    猜你喜欢
    • 1970-01-01
    • 2019-07-16
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    相关资源
    最近更新 更多