PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Kann NLTK in einer gespeicherten Postgres-Python-Prozedur verwendet werden?

Sie können so ziemlich jede Python-Bibliothek in einer gespeicherten PL/Python-Prozedur oder einem Trigger verwenden.

Siehe die PL/Python-Dokumentation .

Konzepte

Der entscheidende Punkt zu verstehen ist, dass PL/Python ist CPython (jedenfalls in PostgreSQL bis einschließlich 9.3); Es verwendet genau denselben Interpreter wie das normale eigenständige Python, es lädt es nur als Bibliothek in das PostgreSQL-Backup. Mit ein paar Einschränkungen (siehe unten), wenn es mit CPython funktioniert, funktioniert es mit PL/Python.

Wenn Sie mehrere Python-Interpreter auf Ihrem System installiert haben – Versionen, Distributionen, 32-Bit vs. 64-Bit usw. – müssen Sie möglicherweise sicherstellen, dass Sie Erweiterungen und Bibliotheken in den richtigen installieren, wenn Sie distutils-Skripte usw. ausführen, aber das ist darüber.

Da Sie jede für das System Python verfügbare Bibliothek laden können, gibt es keinen Grund zu der Annahme, dass NLTK ein Problem darstellen würde, es sei denn, Sie wissen, dass es Dinge wie Threading erfordert, die in einem PostgreSQL-Backend nicht wirklich empfohlen werden. (Tatsächlich habe ich es ausprobiert und es hat "einfach funktioniert", siehe unten).

Eine mögliche Sorge ist, dass der Startaufwand von etwas wie NLTK ziemlich groß sein könnte, Sie möchten wahrscheinlich PL/Python im Postmaster vorladen und das Modul in Ihren Setup-Code importieren, damit es bereit ist, wenn Backends starten. Verstehen Sie, dass der Postmaster der übergeordnete Prozess ist, den alle anderen Backends fork() ausführen Wenn also der Postmaster etwas vorlädt, steht es den Backends mit stark reduziertem Overhead zur Verfügung. Testen Sie die Leistung so oder so.

Sicherheit

Weil Sie beliebige C-Bibliotheken über PL/Python laden können und weil der Python-Interpreter kein echtes Sicherheitsmodell hat, plpythonu ist eine "nicht vertrauenswürdige" Sprache. Skripte haben als postgres vollen und uneingeschränkten Zugriff auf das System Benutzer und kann Zugriffskontrollen in PostgreSQL ziemlich einfach umgehen. Aus offensichtlichen Sicherheitsgründen bedeutet dies, dass PL/Python-Funktionen und -Trigger nur vom Superuser erstellt werden dürfen, obwohl es durchaus sinnvoll ist, GRANT zu verwenden normale Benutzer die Möglichkeit zum Ausführen sorgfältig geschriebene Funktionen, die vom Superuser installiert wurden.

Der Vorteil ist, dass Sie so ziemlich alles tun können, was Sie in normalem Python tun können, wenn Sie bedenken, dass die Lebensdauer des Python-Interpreters die der Datenbankverbindung (Sitzung) ist. Threading wird nicht empfohlen, aber die meisten anderen Dinge sind in Ordnung.

PL/Python-Funktionen müssen mit sorgfältiger Eingabebereinigung geschrieben werden, müssen search_path setzen beim Aufrufen des SPI zum Ausführen von Abfragen usw. Dies wird im Handbuch näher erläutert.

Einschränkungen

Langlaufende oder potenziell problematische Dinge wie DNS-Lookups, HTTP-Verbindungen zu Remote-Systemen, SMTP-Mail-Zustellung usw. sollten im Allgemeinen von einem Hilfsskript aus mit LISTEN erledigt werden und NOTIFY anstelle eines Jobs im Backend, um die Leistung von PostgreSQL zu erhalten und VACUUM nicht zu behindern mit vielen langen Transaktionen. Sie können diese Dinge im Backend tun, es ist nur keine gute Idee.

Sie sollten vermeiden, Threads innerhalb des PostgreSQL-Backends zu erstellen.

Versuchen Sie nicht, eine Python-Bibliothek zu laden, die libpq lädt C-Bibliothek. Dies könnte alle möglichen spannenden Probleme mit dem Backend verursachen. Wenn Sie von PL/Python aus mit PostgreSQL sprechen, verwenden Sie die SPI-Routinen und keine reguläre Client-Bibliothek.

Machen Sie keine sehr lang andauernden Dinge im Backend, Sie verursachen Vakuumprobleme.

Laden Sie nichts, was eine andere Version einer bereits geladenen nativen C-Bibliothek laden könnte - sagen Sie eine andere libcrypto, libssl usw.

Schreiben Sie niemals direkt in Dateien im PostgreSQL-Datenverzeichnis .

PL/Python-Funktionen werden als postgres ausgeführt Systembenutzer auf dem Betriebssystem, sodass sie keinen Zugriff auf Dinge wie das Home-Verzeichnis des Benutzers oder Dateien auf der Client-Seite der Verbindung haben.

Testergebnis

$ yum install python-nltk python-nltk
$ psql -U postgres regress

regress=# CREATE LANGUAGE plpythonu;

regress=# CREATE OR REPLACE FUNCTION nltk_word_tokenize(word text) RETURNS text[] AS $$
          import nltk
          return nltk.word_tokenize(word)
          $$ LANGUAGE plpythonu;

regress=# SELECT nltk_word_tokenize('This is a test, it''s going to work fine');
              nltk_word_tokenize               
-----------------------------------------------
 {This,is,a,test,",",it,'s,going,to,work,fine}
(1 row)

Also wie gesagt:Ausprobieren. Solange der Python-Interpreter, den PostgreSQL für plpython verwendet, die Abhängigkeiten von nltk installiert hat, wird es gut funktionieren.

Hinweis

PL/Python ist CPython, aber ich würde gerne eine PyPy-basierte Alternative sehen, die nicht vertrauenswürdigen Code mit den Sandbox-Funktionen von PyPy ausführen kann.