Django - eigenes SQL-Abfrage

Django, Flask, Bottle, WSGI, CGI…
Antworten
Benutzeravatar
bugzz
User
Beiträge: 20
Registriert: Donnerstag 17. Juni 2010, 11:38

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 ?
Deutsch ist nicht meine Muttersprache
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Du musst zumindest den primary_key mitselektieren. Aber da du nur Werte wie YEAR() brauchst würd ich wirklich auf die Connection zurückgreifen.
Benutzeravatar
bugzz
User
Beiträge: 20
Registriert: Donnerstag 17. Juni 2010, 11:38

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
Deutsch ist nicht meine Muttersprache
BlackJack

@bugzz: Dann schau doch einfach nach!? Die `type()`-Funktion existiert.
Benutzeravatar
bugzz
User
Beiträge: 20
Registriert: Donnerstag 17. Juni 2010, 11:38

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
Deutsch ist nicht meine Muttersprache
Antworten