Seite 1 von 1

Django - eigenes SQL-Abfrage

Verfasst: Montag 5. Juli 2010, 18:48
von bugzz
Hallo, Experte. Irgendwie komme ich mit "custom-queries" nicht weiter.
Laut Doku soll man MyModel.objects.raw() methode verwenden um eigenen/komplitierte Queries auszuführen.

in meinem Fall sind diese zum Ausführen:

Code: Alles auswählen

SELECT YEAR(publication_date) as jahr, COUNT(YEAR(publication_date)) as anzahl
FROM books_book
GROUP BY YEAR(publication_date)
ORDER BY YEAR(publication_date) 
oder

Code: Alles auswählen

SELECT title, publication_date
FROM books_book
WHERE YEAR(publication_date) = <int_value>
ORDER BY publication_date DESC
Ich habe schon folgendes versucht:

Code: Alles auswählen

query = '''SELECT YEAR(publication_date) as jahr, COUNT(YEAR(publication_date)) as anzahl
FROM books_book
GROUP BY YEAR(publication_date)
ORDER BY YEAR(publication_date)'''
year_tags_dict = Book.objects.raw(query)
Bekomme aber Fehlermeldung:
InvalidQuery: Raw query must include the primary key
Es gibt ja auch Connection und Cursor, aber wie weit ich weiß. Methode raw() ist extra für "eigene SQL-Abfragen" da.

P.S. wenn ich versuche die RAW-Abfrage in shell (myproject/manage.py shell) auszuführen, bekomme keine fehlermeldung. Stattdessen bekomme ich nur das:

Code: Alles auswählen

<RawQuerySet: 'SELECT bla-bla-bla'>
Was mache ich falsch? Soll ich doch auf Connection/Cursor zugreifen ?

Re: Django - eigenes SQL-Abfrage

Verfasst: Montag 5. Juli 2010, 23:39
von apollo13
Du musst zumindest den primary_key mitselektieren. Aber da du nur Werte wie YEAR() brauchst würd ich wirklich auf die Connection zurückgreifen.

Re: Django - eigenes SQL-Abfrage

Verfasst: Dienstag 6. Juli 2010, 19:15
von bugzz
Ok. Ich habs schon (..total unprofessionell) :oops: :evil:
Was mich jetzt noch stört...mir ist immer noch unklar in welcher Form ich die daten zurück bekommene ? Ich benutze fetchall() methode und versteh nicht ob es ein dictionary, ein tupel oder eine liste zurückgegeben wird? :K

Re: Django - eigenes SQL-Abfrage

Verfasst: Dienstag 6. Juli 2010, 19:51
von BlackJack
@bugzz: Dann schau doch einfach nach!? Die `type()`-Funktion existiert.

Re: Django - eigenes SQL-Abfrage

Verfasst: Sonntag 11. Juli 2010, 21:10
von bugzz
Hmm habs endlich hingekriegt mit dem raw() Methode und finde diese wesentlich besser als connection und cursor. Musste zwar in jeder query ID mitselektieren, dafür aber ist es, meiner Meinung nach, einfacher die ergebnisse angezeigt/modifitiert zu bekommen.

Code: Alles auswählen

pub_tags_advanced_query = '''SELECT p.id, p.name as verlag, count(p.name) as anzahl
                             FROM books_publisher p LEFT JOIN books_book b ON p.id = b.publisher_id
                             GROUP BY p.name
                             ORDER BY p.name'''
year_tags_advanced_query = '''SELECT id, year(publication_date) as jahr, count(year(publication_date)) as anzahl
                              FROM django.books_book
                              GROUP BY year(publication_date) ORDER BY year(publication_date)'''


....
year_tags_RQS/pub_tags_RQS = <modell>.objects.raw(year_tags_advanced_query/pub_tags_advanced_query)
...
welcher typ ?

Code: Alles auswählen

>>> print type(year_tags_RQS/pub_tags_RQS).__name__
RawQuerySet
template

Code: Alles auswählen

...
<fieldset>
                <legend>Verlag-Tags</legend>
                <p>
                    {% for pub_tag in pub_tags_RQS%}
                        <a href="/books/publisher/{{pub_tag.id}}">
                           {{pub_tag.verlag}}&nbsp;[{{pub_tag.anzahl}}]</a>
                    {% empty %}
                        Keine pub_tags
                    {% endfor %}
                </p>
            </fieldset>
...
ähnlich mit dem Erscheinungsjahr

Das gaze errinert mich an PHP mit Mysqli_fetch_object

P.S. @ BlackJack
Danke für den Tipp. Hat mit sehr geholfen