Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raw query must include the primary key

Tags:

I got a raw SQL statement in my views.py

Message.objects.raw('''
        SELECT s1.ID, s1.CHARACTER_ID, MAX(s1.MESSAGE) MESSAGE, MAX(s1.c) occurrences
        FROM
           (SELECT ID, CHARACTER_ID, MESSAGE, COUNT(*) c
            FROM tbl_message WHERE ts > DATE_SUB(NOW(), INTERVAL %s DAY) GROUP BY CHARACTER_ID,MESSAGE) s1
        LEFT JOIN
           (SELECT ID, CHARACTER_ID, MESSAGE, COUNT(*) c
            FROM tbl_message WHERE ts > DATE_SUB(NOW(), INTERVAL %s DAY) GROUP BY CHARACTER_ID,MESSAGE) s2
          ON s1.CHARACTER_ID=s2.CHARACTER_ID
         AND s1.c < s2.c
        WHERE s2.c IS NULL
        GROUP BY CHARACTER_ID
        ORDER BY occurrences DESC''', [days, days])

The result of this SQL statement (tested on database directly) is:

ID  | CHARACTER_ID | MESSAGE | OCCURENCES
----+--------------+---------+--------------
148 | 10           | test    | 133

But all I got is a InvalidQuery Exception with the information Raw query must include the primary key

Then I double checked the docs and read:

There is only one field that you can’t leave out - the primary key field....An InvalidQuery exception will be raised if you forget to include the primary key.

As you can see I got the requested primary key added in my statement. What's wrong?

class Message(models.Model):
    character = models.ForeignKey('Character')
    message = models.TextField()
    location = models.ForeignKey('Location')
    ts = models.DateTimeField()

    class Meta:
        pass

    def __unicode__(self):
        return u'%s: %s...' % (self.character, self.message[0:20])
like image 631
Thomas Schwärzl Avatar asked Jun 27 '13 15:06

Thomas Schwärzl


People also ask

What exception is raised if the primary key is excluded from a raw query?

An InvalidQuery exception will be raised if you forget to include the primary key.

What is raw queries in Django?

The raw() manager method can be used to perform raw SQL queries that return model instances: Manager. raw (raw_query, params=(), translations=None) This method takes a raw SQL query, executes it, and returns a django.


1 Answers

Include 1 as id to your query

Message.objects.raw('''
        SELECT 1 as id , s1.ID, s1.CHARACTER_ID, MAX(s1.MESSAGE) MESSAGE, MAX(s1.c) occurrences
        FROM
           (SELECT ID, CHARACTER_ID, MESSAGE, COUNT(*) c
            FROM tbl_message WHERE ts > DATE_SUB(NOW(), INTERVAL %s DAY) GROUP BY CHARACTER_ID,MESSAGE) s1
        LEFT JOIN
           (SELECT ID, CHARACTER_ID, MESSAGE, COUNT(*) c
            FROM tbl_message WHERE ts > DATE_SUB(NOW(), INTERVAL %s DAY) GROUP BY CHARACTER_ID,MESSAGE) s2
          ON s1.CHARACTER_ID=s2.CHARACTER_ID
         AND s1.c < s2.c
        WHERE s2.c IS NULL
        GROUP BY CHARACTER_ID
        ORDER BY occurrences DESC''', [days, days]) 
like image 184
Tinashe Robert Avatar answered Sep 18 '22 13:09

Tinashe Robert