http://danielkeppler.com

mein Blog über Guatemala und SEO

4 Dinge für NoSQL Django Programmierer wissen

Dies ist der erste Beitrag in einer Reihe, geben Sie sollten einen Eindruck von dem, was nicht-relationale / NoSQL Modell -Code sieht wie mit django- nonrel. Wie in der genannten previous post. Sie können django- nonrel in Aktion zu sehen auf unsere neue Website (Wir benutzen es selbst im Geiste der Dogfooding).

Zwar sollte auch hier alles auf allen nonrel DBs arbeiten wir derzeit nur eine erörtert App Engine Backend und bald ein MongoDB Backend ( Mehr dazu , sobald es fertig ist ). Wenn Sie mit anderen Backends zu helfen (Redis, SimpleDB, CouchDB, Etc.) bitten wir Sie, die Diskussionsgruppe.

Wir werden in den Quellcode des Tauchgangs unserer Website enthält, die einen sehr einfachen “CMS” und ein Blog app , die mehrere unabhängige Blogs hosten können. Es läuft das Admin-Interface unverändert, aber mit einigen Einschränkungen. Insgesamt ist der Code überraschend ähnlich wie bei normalen Django -Code , aber Sie werden auch feststellen, dass nonrel -kompatiblen Modellen ihren eigenen Weg des Denkens müssen. Was braucht es, um eine Website, die nonrel -kompatibel ist, zu schreiben? Let’s get rollen .

Einrichten der Umgebung

Sie müssen Python 2.5 oder 2.6 . Einfach downloaden und entpacken und passen settings.py . Dieses Paket enthält Django nonrel und alle anderen Abhängigkeiten außer der App Engine SDK. Wenn Sie die neueste Repository- Code verwenden, können Sie alternativ einen Blick auf die manuelle Installationsanleitung. Diese Seite beschreibt auch, wie Sie die neueste installieren App Engine SDK auf unterschiedlichen Betriebssystemen .

Sie können jetzt einfach manage.py syncdb, manage.py createsuperuserUnd manage.py runserver as usual. Schließlich können Sie die Website zu implementieren via App Engine manage.py bereitstellen. Dieser wird automatisch ausgeführt syncdb auf dem Produktiv-Server . Wenn Sie eine Eingabeaufforderung auf dem Server auszuführen Produktion Präfix mit “remote” . Zum Beispiel: ” manage.py remote shell ” . Dies funktioniert nur , wenn Sie Ihre Website bereitgestellt , obwohl .

Nun lassen Sie eintauchen in die eigentliche Code und erleben Sie die Unterschiede.

JOINs sind böse

Als unsere erste App schrieben wir einen minimalen CMS. Nun könnte man fragen, warum können wir nicht nur nutzen django.contrib.flatpages?

Offensichtliche JOINs …

Leider Flatpages hat eine Viele-zu -viele- Beziehung zu Standort das heißt, wir brauchen JOINs ( jede Abfrage, die Spannweiten Modell Beziehungen via “__“Bedürfnisse JOINs ). Nonrel DBs in der Regel können Sie nur einfache AND- Filter-Regeln auf ein einziges Modell angeben (”table” ). Wir konnten eine In-Memory JOIN tun , indem Sie mehrere Abfragen manuell und Kombination der Ergebnisse , aber dies würde unsere Code unnötig komplex. Ich werde später über alternative Lösungen sprechen. Da haben wir nur eine Domain brauchen wir nicht Standort, So let’s machen unsere eigenen Flatpages Alternative.

… und nicht so offensichtlich JOINs

Wir haben gerade die Flatpages Middleware kopiert und begann mit einem frischen Modell ( beachten Sie , wird der Code vereinfacht, um die wichtigen Teile leichter zu sehen ):

# minicms / models.py :

# Definieren Sie eine abstrakte Basisklasse , die für unsere Blogeinträge wiederverwendet werden können
Klasse BaseContent(Modelle.Modell):
    Titel = Modelle.CharField(max_length=200)
    Inhalt = Modelle.TextField(leer=Wahr)

    Klasse Meta:
        Zusammenfassung = Wahr

Klasse Seite(BaseContent):
    URL = Modelle.CharField("URL", max_length=200)

Das einzige, was zu beachten ist, dass wir eine Definition Zusammenfassung Basisklasse (Meta -Klasse : abstract = True) Für die Seite Modell-und später auch den Blog Post Modell. Diese Basisklasse kümmern Erzeugung der Wiki-Markup zu nehmen, so dass der Code hochgeladen werden können durch Seite und Post später. Der wichtige Punkt ist , dass die Basisklasse müssen abstrakt sein , weil sonst wird Django Multi-Tisch- Vererbung (dh , das Basismodell Einsatz hat seinen eigenen Tisch und das Kind bekommt eine separate Tabelle enthält nur die zusätzlichen Felder ). Da dies erfordern würde JOINs müssen wir halten unsere Modelle “flat” , indem Sie nur abstrakte Modelle.

Keine Überraschungen in einfachen Code

Nun, ich habe nur auf diesen Umstand hinzuweisen . Werfen wir einen kurzen Blick auf die zeigen Profil (das wird von den veränderten Flatpages Middleware verwendet):

# minicms / views.py :

def zeigen(Antrag, URL):
    wenn nicht URL.startswith('/'):
        URL = '/' + URL
    Seite = get_object_or_404(Seite, URL=URL)
    Rückkehr direct_to_template(Antrag, " minicms / page_detail.html ",
        {' Seite ': Seite})

Wie Sie sehen können , gibt es keine Magie, hier. Einfache Anfragen vertraut aussehen . Wahrscheinlich haben Sie das schon geahnt . Doh ! :)

Datum Abfragen können Sie beißen

OK , wir wollen auch mehrere Blogs auf unserer Website haben , so brauchen wir sowohl eine Post und ein Blog Modell:

# blog / models.py :

Klasse Blog(Modelle.Modell):
    base_url = Modelle.CharField(" Base URL ", max_length=200,
        help_text=' Beispiel: Bei Basis-URL "persönliche" Ihre Blog-Posts würden '
                  ' werden unter / blog / persönliche /...')
    Titel = Modelle.CharField(max_length=200)
    Beschreibung = Modelle.CharField(max_length=500, leer=Wahr')

Klasse Post(BaseContent):
    blog = Modelle.ForeignKey(Blog, related_name="Stellen")
    veröffentlicht = Modelle.BooleanField(Default=Falsch)
    Autor = Modelle.ForeignKey(Benutzer, related_name="Stellen")
    URL = Modelle.CharField("URL", leer=Wahr, max_length=200)
    published_on = Modelle.DateTimeField(nichtig=Wahr, leer=Wahr)

Wie Sie sehen können , Post leitet sich aus BaseContent, So erbt Wiki-Markup Handling und die Titel und Inhalt Felder. Alles hier sieht ziemlich normal. Der Unterschied liegt in den Blick :

# blog / views.py :

def zeigen(Antrag, blog_url, Jahr, Monat, post_url):
    versuchen:
        Start = datetime(int(Jahr), int(Monat), 1)
        Ende = datetime(int(Jahr), int(Monat)+1, 1)
    ausgenommen ValueError:
        erhöhen Http404(" Format "Datum nicht korrekt ")
    blog = get_object_or_404(Blog, base_url=blog_url)
    Post = get_object_or_404(Post, URL=post_url, blog=blog,
        published_on__gte=Start, published_on__lt=Ende)
    Rückkehr direct_to_template(Antrag, 'Blog / post_detail.html ",
        {'Post': Post, 'Blog': blog})

def blättern(Antrag, blog_url):
    blog = get_object_or_404(Blog, base_url=blog_url)
    Abfrage = Post.Objekte.Filter(blog=blog, veröffentlicht=Wahr)
    Abfrage = Abfrage.order_by('- published_on ")
    Rückkehr object_list(Antrag, Abfrage, paginate_by=POSTS_PER_PAGE,
        extra_context={'Blog': blog})

Der zeigen Angesichts tut etwas ungewöhnlich. Mit SQL formulieren Sie normalerweise das Datum als Abfrage

Post = get_object_or_404(Post, URL=post_url, blog=blog,
    published_on__year=Jahr, published_on__month=Monat)

Es gibt keinen einfachen Weg, Ausdruck einer “__month =“Abfrage bei den meisten nicht-relationalen Backends . Während dieser speziellen Abfrage könnte erkannt und ausgeführt werden , weil es auch ein “__year =“Filter würde dies nicht-triviale Komplexität der Backend hinzufügen, so dass wir ihn nicht unterstützen auf diese Weise entschieden. Denn jetzt haben wir die Version, die hässlicher einen Datumsbereich Abfrage verwendet zu verwenden. Wir werden eine flexible Lösung für alle geben nonrel Backends in die Zukunft , obwohl .

Es gibt etwas, das Sie vielleicht bemerkt haben . In zeigen und blättern wir zunächst den Blog abzurufen und dann die Post (s) . Das ist nicht unbedingt ungewöhnlich, aber mit SQL konnten wir haben gerade die abgerufenen Post direkt über Post.objects.filter ( = blog__url blog_url , ...). Diese müssten JOIN Unterstützung, wenn auch .

Neat -o -Emulation Features

Schließlich der letzte Punkt : Wir haben keine select_related () in unsere Anfragen , aber das wäre eine sehr nützliche Optimierung werden. Dies ist noch nicht unterstützt . Also , was können Sie tun? Derzeit löst alle diese durch Hacken um die Beschränkungen und mehr Code schreiben . : ‘(

Allerdings können die meisten dieser Probleme gelöst werden transparent . Wir planen, eine unabhängige Schicht, die am Anfang der nonrel Backend sitzt und emuliert viele der NEAT -o Funktionen, die Sie gerne von SQL (zB JOINs und Datum Abfragen) hinzuzufügen. Wie wird es Skala, wenn ? Diese Schicht konnte Pflege von automatischen nehmen Denormalisierung und MapReduce, So liest könnte Ihr Umfang, sondern auch komplexe Zusammenhänge kann eine Menge Rechenleistung zu halten aktualisiert werden. Du wirst noch an Ihrem Modell Code sorgfältig Design und nicht alles wird praktisch. Es macht viel mehr möglich, obwohl .

Dort beginnt der Spaß , weil Sie scheinbar SQL – Code Django nur laufen konnte (mit JOINs und Aggregate) effizient auf einem nonrel DB – zum Preis von eventuelle Konsistenz. Dennoch sind die Möglichkeiten riesig! Das ist der eigentliche Grund, warum wir arbeiten django- nonrel.

Also, was die Take-Aways sind ?

  • Einfach zu vermeiden und JOINs oder Abfragen ( als ob das noch einfach; ). Sie können in “unerwarteten” Orten wie Vererbung Modell , obwohl erscheinen.
  • Auch, Datum Abfragen nicht funktionieren.
  • Einfache Anfragen können die gleichen wie immer sein.
  • Djangos ORM wird für transparente Emulation von SQL-Features in der Zukunft ermöglichen.

ähnliche Beiträge:

Wenn dir unser Beitrag gefallen hat, setze doch einen Link auf diesen Beitrag. Hier ein Code Beispiel:

<a href="http://danielkeppler.com/2010/4-dinge-fuer-nosql-django-programmierer-wissen/">4 Dinge für NoSQL Django Programmierer wissen</a>

Leave a Reply