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 update RUN apt-get -y install python3 RUN apt-get -y install python3-pip RUN 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