sql >> Database >  >> RDS >> PostgreSQL

Kan NLTK worden gebruikt in een Postgres Python Stored Procedure?

Je kunt vrijwel elke Python-bibliotheek gebruiken in een PL/Python-opgeslagen procedure of trigger.

Zie de PL/Python-documentatie .

Concepten

Het cruciale punt om te begrijpen is dat PL/Python is CPython (in ieder geval in PostgreSQL tot en met 9.3); het gebruikt precies dezelfde interpreter als de normale stand-alone Python, het laadt het gewoon als een bibliotheek in de PostgreSQL-back-up. Met een paar beperkingen (hieronder beschreven), als het werkt met CPython, werkt het ook met PL/Python.

Als u meerdere Python-interpreters op uw systeem hebt geïnstalleerd - versies, distributies, 32-bits versus 64-bits enz. - moet u er misschien voor zorgen dat u extensies en bibliotheken in de juiste installeert wanneer u distutils-scripts uitvoert, enz. erover.

Aangezien je elke bibliotheek die beschikbaar is voor het systeem Python kunt laden, is er geen reden om te denken dat NLTK een probleem zou zijn, tenzij je weet dat het dingen vereist zoals threading die niet echt worden aanbevolen in een PostgreSQL-backend. (Ja hoor, ik heb het geprobeerd en het "werkte gewoon", zie hieronder).

Een mogelijke zorg is dat de opstartoverhead van zoiets als NLTK behoorlijk groot kan zijn, je wilt waarschijnlijk PL/Python het vooraf laden in de postmaster en de module in je setup-code importeren, zodat het klaar is wanneer de backends starten. Begrijp dat de postmaster het bovenliggende proces is dat alle andere backends fork() van, dus als de postmaster iets vooraf laadt, is het beschikbaar voor de backends met sterk verminderde overhead. Test de prestaties hoe dan ook.

Beveiliging

Omdat je willekeurige C-bibliotheken kunt laden via PL/Python en omdat de Python-interpreter geen echt beveiligingsmodel heeft, plpythonu is een "niet-vertrouwde" taal. Scripts hebben volledige en onbeperkte toegang tot het systeem als de postgres gebruiker en kan vrij eenvoudig toegangscontroles in PostgreSQL omzeilen. Om voor de hand liggende veiligheidsredenen betekent dit dat PL/Python-functies en triggers alleen door de superuser mogen worden aangemaakt, hoewel het redelijk is om GRANT normale gebruikers de mogelijkheid om uit te voeren zorgvuldig geschreven functies die door de superuser zijn geïnstalleerd.

Het voordeel is dat je vrijwel alles kunt doen wat je kunt doen in normale Python, rekening houdend met het feit dat de levensduur van de Python-interpreter die van de databaseverbinding (sessie) is. Inrijgen wordt niet aanbevolen, maar de meeste andere dingen zijn prima.

PL/Python-functies moeten worden geschreven met zorgvuldige invoersanering, moeten search_path instellen bij het aanroepen van de SPI om query's uit te voeren, enz. Dit wordt meer besproken in de handleiding.

Beperkingen

Langlopende of potentieel problematische zaken zoals DNS-lookups, HTTP-verbindingen met externe systemen, SMTP-mailbezorging, enz. moeten over het algemeen worden gedaan vanuit een helperscript met behulp van LISTEN en NOTIFY in plaats van een in-backend-taak om de prestaties van PostgreSQL te behouden en te voorkomen dat VACUUM wordt belemmerd met veel lange transacties. Je kunt deze dingen in de backend doen, het is gewoon geen goed idee.

Vermijd het maken van threads binnen de PostgreSQL-backend.

Probeer geen Python-bibliotheek te laden die de libpq . laadt C-bibliotheek. Dit kan allerlei spannende problemen veroorzaken met de backend. Gebruik bij het praten met PostgreSQL vanuit PL/Python de SPI-routines en niet een gewone clientbibliotheek.

Doe geen langlopende dingen in de backend, dat veroorzaakt vacuümproblemen.

Laad niets dat een andere versie van een reeds geladen native C-bibliotheek zou kunnen laden - zeg een andere libcrypto, libssl, enz.

Schrijf niet rechtstreeks naar bestanden in de PostgreSQL-gegevensdirectory, ooit .

PL/Python-functies worden uitgevoerd als de postgres systeemgebruiker op het besturingssysteem, zodat ze geen toegang hebben tot zaken als de thuismap van de gebruiker of bestanden aan de clientzijde van de verbinding.

Testresultaat

$ 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)

Dus, zoals ik al zei:probeer het. Zolang de Python-interpreter die PostgreSQL voor plpython gebruikt de afhankelijkheden van nltk heeft geïnstalleerd, werkt het prima.

Opmerking

PL/Python is CPython, maar ik zou graag een op PyPy gebaseerd alternatief zien dat niet-vertrouwde code kan uitvoeren met behulp van de sandbox-functies van PyPy.




  1. Invoegefficiëntie van een grote hoeveelheid gegevens met SQL

  2. Waarom staat MySQL toe om een ​​NOT NULL-kolom bij te werken naar NULL?

  3. Hoe de grootte van de blob in PHP of SQL krijgen

  4. Mysql - optimalisatie - meerdere group_concat &joins met behulp van hebben