Instalando e usando Python 3 + plpythonu3 no PostgreSQL

O PostgreSQL permite criar funções e stored procedures em Python 3 com a extensão plpythonu3.

No tutorial abaixo criaremos uma imagem docker com PostgreSQL 13 + Python 3 (3.7) e o plpython3

Crie um pasta e nele crie um arquivo novo chamado Dockerfile com o seguinte conteúdo:

FROM postgresRUN apt-get updateRUN apt-get -y install python3RUN apt-get -y install python3-pipRUN apt-get -y install postgresql-plpython3-13

Agora faça o docker criar uma imagem a partir desse Dockerfile

docker build -t postgresql-python .

Crie um conteiner usando a imagem recém criada

docker run -d --name postgresql-python -P -e POSTGRES_PASSWORD=postgres postgresql-python

Se conecte ao banco de dados dados e execute o comando com uma conta de super usuário:

CREATE EXTENSION plpython3u;

Pronto! Já pode usar funções com Python 3 dentro do PostgreSQL

DO $$import sysplpy.notice(sys.version_info)$$ LANGUAGE 'plpython3u';

Criando uma função que mostra a versão do Python

CREATE FUNCTION python_version()  RETURNS textAS $$  import sys  return sys.version_info$$ LANGUAGE plpython3u;

SELECT python_version();

Verificando com qual usuário os comandos em python são executados

DO $$import subprocessfrom subprocess import Popenp = Popen(["whoami"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)output, errors = p.communicate()plpy.notice(output)# Retorna: postgresplpy.notice(errors)$$ LANGUAGE 'plpython3u';

Instale uma biblioteca utilizando um usuário root (se você utilizar o usuário postgres a biblioteca não irá funcionar)

pip3 install -U scikit-learn

Verificando a versão do scikit-learn

DO $$import sklearnplpy.notice("sklearn version: " + sklearn.__version__)# NOTICE:  sklearn version: 0.24.2# DO$$ LANGUAGE 'plpython3u';

Executando correlação de pearson e spearman

DO $$def getValue(v):  return v["unnest"]x = plpy.execute("SELECT unnest('{1,2,3,4,5}'::INT[])")y = plpy.execute("SELECT unnest('{1,2,3,4,5}'::INT[])")x = list(map(getValue,x))y = list(map(getValue,y))import scipyfrom scipy import statsplpy.notice(stats.pearsonr(x,y)[0])plpy.notice(stats.spearmanr(x,y)[0])$$ LANGUAGE 'plpython3u';

Referências

Resposta no StackOverflow
https://stackoverflow.com/questions/64045127/how-to-install-plpython-for-postgres

Documentação Oficial
https://www.postgresql.org/docs/current/plpython-funcs.html

Documentação Oficial - Funções úteis
https://www.postgresql.org/docs/current/plpython-util.html

Usando Popen no Python3
https://queirozf.com/entries/python-3-subprocess-examples#popen-example-run-command-and-get-return-code

You should also read:

NOTIFY e LISTEN no PostgreSQL

Função Trigger (Trigger Function) genérica para avisar modificações (INSERT, UPDATE E DELETE) em tabelas no PostgreSQL Esta função envia uma mensagem NOTIFY para…