如何将此SQL查询转换为Django ORM

x759pob2  于 2023-03-31  发布在  Go
关注(0)|答案(1)|浏览(239)

我有以下SQL查询:

SELECT messages1.id, messages1.channel FROM (SELECT * FROM messages WHERE timestamp >= datetime.now() AND channel IN ('ALL', 'UC')) messages1 LEFT JOIN read_messages ON messages1.id = read_messages.message_id WHERE read_messages.id IS NULL;

这些是我的模特

from django.db import models

class Messages(models.Model):
    channel = models.TextField(blank=True, null=True)
    message = models.TextField(blank=True, null=True)
    timestamp = models.TextField(blank=True, null=True)
    publisher = models.IntegerField(blank=True, null=True)
    type = models.CharField(max_length=5)

    class Meta:
        managed = False
        db_table = 'messages'

class NotifiedMessages(models.Model):
    id = models.IntegerField(primary_key=True)
    user_id = models.IntegerField()
    message_id = models.IntegerField()

    class Meta:
        managed = False
        db_table = 'notified_messages'

class ReadMessages(models.Model):
    user_id = models.IntegerField(blank=True, null=True)
    message_id = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'read_messages'

我已经尝试使用子查询和其他东西,但现在的主要问题是子查询返回错误:django.db.utils.ProgrammingError: subquery must return only one column
因为我想做这样的事

ts = Messages.objects.filter(timestamp__gte=datetime.today(), channel__in=['ALL', 'UC'])
Messages.objects.annotate(messages1=Subquery(ts, output_field=models.CharField()))

上面的代码有什么问题?2我该怎么做才能正确地翻译查询?

xzv2uavs

xzv2uavs1#

看起来你试图以错误的方式使用子查询作为注解。子查询用于根据另一个查询集中的值过滤查询集。
下面是如何使用子查询的示例。

from django.db.models import Q, Subquery, OuterRef

now = datetime.now()

read_message_subquery = ReadMessages.objects.filter(
    user_id=user_id,
    message_id=OuterRef('id')
).values('message_id')

query = Messages.objects.filter(
    timestamp__gte=now,
    channel__in=['ALL', 'UC'],
).exclude(id__in=Subquery(read_message_subquery)).values('id', 'channel')

相关问题