2015-11-12 3 views
5

Ich habe eine glänzende Anwendung entwickelt. Wenn es gestartet wird, lädt es EINMAL einige Datentabellen. Etwa 4 GB Datentabellen. Anschließend können Benutzer, die eine Verbindung zur App herstellen, die Benutzeroberfläche verwenden und mit diesen Datentabellen spielen.Django-Anwendung mit einem großen Panda-Objekt, das für alle Anfragen freigegeben wurde?

Diese Anwendung ist nett, hat aber einige Einschränkungen. Deshalb suche ich nach einer anderen Lösung.

Meine Idee ist es, Pandas und Django zusammenarbeiten zu lassen. Auf diese Weise konnte ich gleichzeitig eine Schnittstelle und eine RESTful-API entwickeln. Aber was ich brauche, ist, dass alle Anfragen, die nach Django kommen, Pandas-Databases verwenden können, die einmal geladen wurden. Stellen Sie sich vor, wenn für jede Anfrage 4 GB Speicher geladen werden müssten ... Es wäre schrecklich.

Ich habe überall gesucht, konnte aber keinen Weg finden, dies zu tun. Ich habe diese Frage gefunden: https://stackoverflow.com/questions/28661255/pandas-sharing-same-dataframe-across-the-request Aber es hat keine Antworten.

Warum muss ich die Daten im RAM haben? Weil ich Leistung brauche, um die gewünschten Ergebnisse schnell zu rendern. Ich kann MariaDB nicht bitten, diese Daten zu berechnen und zu pflegen, zum Beispiel, weil es einige Berechnungen beinhaltet, die nur R oder ein spezialisiertes Paket in Python oder anderen Sprachen machen können.

Antwort

2

Ich habe einen ähnlichen Anwendungsfall, wo ich ein bestimmtes Objekt nur einmal laden (instanziieren) und in allen Anfragen verwenden möchte, da es einige Zeit (Sekunden) benötigt, um die Verzögerung zu laden für jede Anfrage vorstellen.

Ich verwende eine Funktion in Django>=1.7, die AppConfig.ready() Methode, um dies nur einmal zu laden. Hier

ist der Code:

# apps.py 
from django.apps import AppConfig 
from sexmachine.detector import Detector 

class APIConfig(AppConfig): 
    name = 'api' 

    def ready(self): 
     # Singleton utility 
     # We load them here to avoid multiple instantiation across other 
     # modules, that would take too much time. 
     print("Loading gender detector..."), 
     global gender_detector 
     gender_detector = Detector() 
     print("ok!") 

Dann, wenn Sie es verwenden möchten:

from api.apps import gender_detector 
gender_detector.get_gender('John') 

Legen Sie die Datentabelle in der ready() Methode und dann von überall verwenden. Ich gehe davon aus, dass die Tabelle für jeden WSGI-Mitarbeiter einmal geladen wird, seien Sie also vorsichtig.

+0

Hallo dukebody, Danke für Ihre Antwort! Es sieht gut aus. Denken Sie, dass es möglich ist, die Anzahl der WSGI-Mitarbeiter zu begrenzen? Und bereiten Sie alle mit den Daten vor? Es wäre perfekt ! Einen schönen Tag, Jerome – FrelonQuai

+0

Sie können die Anzahl der WSGI-Mitarbeiter leicht begrenzen. Zum Beispiel in Gunicorn benutzen 'gunicorn wsgi_app_object --worker '. – dukebody

+0

Danke für deine Antwort dukebody! Ich denke, dass es das Ding tun kann! – FrelonQuai

0

Ich mag das Problem missverstehen, aber zu mir eine 4 GB-Datenbanktabelle zu haben, die von Benutzern leicht zugänglich ist, sollte kein allzu großes Problem sein. Ist es falsch, die Daten nur einmal im Voraus zu laden, wie Sie es beschrieben haben? 4GB ist jetzt nicht zu viel RAM.

Persönlich würde ich empfehlen, Sie verwenden nur das Datenbanksystem selbst, anstatt Sachen in den Speicher zu laden und mit Python zu knacken. Wenn Sie die Daten richtig einrichten, können Sie in wenigen Sekunden viele tausend Abfragen erstellen. Pandas wird tatsächlich geschrieben, um SQL nachzuahmen, so dass der Großteil des Codes, den Sie verwenden, wahrscheinlich direkt in SQL übersetzt werden kann. Vor kurzem hatte ich eine Situation bei der Arbeit, wo ich eine große Join-Operation im Wesentlichen auf ein paar hundert Dateien (~ 4 GB insgesamt, 600.000 Zeilen pro Datei) mit Pandas eingerichtet. Die gesamte Ausführungszeit betrug 72 Stunden oder so und dies war eine Operation, die einmal pro Stunde ausgeführt werden musste. Ein Kollege schrieb den gleichen Python/Pandas-Code als eine ziemlich einfache SQL-Abfrage um, die in 5 Minuten statt in 72 Stunden endete.

Wie auch immer, ich empfehle Ihnen, Ihren Pandas Datenrahmen in einer aktuellen Datenbanktabelle zu speichern. Django basiert auf einer Datenbank (normalerweise mySQL oder Postgres) und Pandas hat sogar eine Funktion, um Ihren Datenrahmen direkt in die Datenbank dataframe.to_sql('database_connection_str') einzufügen! Von dort aus können Sie den Django-Code so schreiben, dass die Antworten eine einzelne Abfrage an die Datenbank senden, Werte abrufen und Daten zeitgerecht zurückgeben.

+0

Hallo chill_turner und danke für deine Antwort. Wenn ich sage, dass die Daten ONCE geladen werden, ich meine, es ist einmal Server-Seite geladen. Und niemals Kundenseite. Der Client kann die Schnittstelle verwenden, eine Anfrage wird an Shiny gesendet und Shiny liefert eine Antwort. Wenn ich Ihren Zweck gut verstehe, würde es darin bestehen, mariaDB Tabellen IN MEMORY zu haben? Mein Problem damit ist, dass MariaDB einige Operationen nicht ausführen kann. Stellen Sie sich vor, Sie möchten nach aField gruppieren und haben die erste und dritte Zeile jeder Gruppe (sortiert nach einem anderenFeld). Oder ein paar andere Dinge, die in MariaDB nicht verfügbar sind? – FrelonQuai

+0

Hallo - Ich erinnere mich nicht wirklich daran, MariaDB zu erwähnen, aber Sie können es verwenden, wenn Sie möchten. Ich würde Postgres oder Mysql verwenden, da sie gut mit Django spielen. Sobald Sie Daten in die Django-Datenbank geladen haben, schreiben Sie Python-Code, der sagt: "Okay, wenn der Benutzer auf Seite X geht, werden wir diese drei Funktionen ausführen, die einen Aufruf an die Datenbank machen und etwas verarbeitetes Zeug zurückgeben. Genau dafür sind Django (und andere ähnliche Web-Frameworks) geschaffen! –

Verwandte Themen