Falando "Postgrês"

download Falando "Postgrês"

of 79

  • date post

    22-Jan-2018
  • Category

    Software

  • view

    63
  • download

    3

Embed Size (px)

Transcript of Falando "Postgrês"

  • FALANDO "POSTGRS"DICKSON S. GUEDES

    22 PYTHONFLORIPA MEETUPhttps://youtu.be/tB0uNqjwbX8?t=7h14m57s

    https://youtu.be/tB0uNqjwbX8?t=7h14m57s

  • BEGIN TRANSACTION;Por que estamos aqui hoje?

  • AVISO IMPORTANTEEsta palestra conter cenas fortes de assassinato s boas

    prticas de cdigos.

    Tambm conter cdigos que provocaro os mais diferentesestmulos musculares em sua face. `(leia-se "sua face" mesmo,

    e no "seu feice")

    Existe o risco de que alguns paradigmas seus sejamquebrados.

    Voc pode querer comear a se retirar tudo bem

  • EMACS ROCKS!Esta palestra totalmente escrita e apresentada utilizando oeditor de texto Emacs com org-mode `(leia-se "no vai ter

    memes")

    e este talvez seja o primeiro paradigma a ser quebrado

    Alm de uma tela preta e apresentao em texto voc vercdigos em Python e em SQL sendo reproduzidos aqui dentro

    mesmo

    PS: ainda d tempo de sair

  • SEM MEMES?

  • VAMOS ENTO COMEAR?A language that doesn't affect the way you think about

    programming, is not worth knowing. - Alan Perlis

    Ento vamos conhecer um pouco mais das relaes entre oPython e o Elefante?

  • LICENA

  • PYTHONGPL Compatvel

    https://docs.python.org/3/license.html

  • POSTGRESQLPostgreSQL License

    https://www.postgresql.org/about/licence/

  • PADRES

  • PEP1-8: Guidelines, Code Style, 20: The Zen of Python248: Database API Spec v1.0249: Database API Spec v2.0257: Docstring

  • SQL (ISO/IEC)92: CLI, PSM, DATETIME, UNION, ,INFORMATION_SCHEMA, CAST, 1999: MED, OLB, JRT, GROUP BY, ROLLUP, WITHRECURSIVE2003: XML, Window Functions, SEQUENCES, MERGE*2006: XML, XQuery2008: TRUNCATE, Partitioned JOIN2011: Temporal2016: JSON, Row Pattern Matching

  • DOCUMENTAOhttps://www.postgresql.org/docs/https://www.postgresql.org/docs/current/static/index.htmlhttps://www.postgresql.org/docs/9.6/static/index.htmlhttps://www.postgresql.org/docs/9.5/static/index.html

    https://www.postgresql.org/docs/https://www.postgresql.org/docs/current/static/index.htmlhttps://www.postgresql.org/docs/9.6/static/index.htmlhttps://www.postgresql.org/docs/9.5/static/index.html

  • OOrespirem

  • EXTENSIBILIDADE

  • ESTENDENDO PYTHONPython

    import spamstatus = spam.system("ls -l")

    C#include

    static PyObject *spam_system(PyObject *self, PyObject *args){ const char *command; int sts;

    if (!PyArg_ParseTuple(args, "s", &command)) return NULL; sts = system(command); return Py_BuildValue("i", sts);}

  • ESTENDENDO POSTGRESQL

  • VIA CATLOGO# \dt pg_catalog. List of relations Schema | Name | Type | Owner ------------+-------------------------+-------+---------- pg_catalog | pg_aggregate | table | postgres ... pg_catalog | pg_class | table | postgres ... pg_catalog | pg_database | table | postgres pg_catalog | pg_foreign_data_wrapper | table | postgres pg_catalog | pg_foreign_server | table | postgres pg_catalog | pg_foreign_table | table | postgres pg_catalog | pg_index | table | postgres ... pg_catalog | pg_language | table | postgres ... pg_catalog | pg_operator | table | postgres ... pg_catalog | pg_type | table | postgres pg_catalog | pg_user_mapping | table | postgres

  • FUNES, OPERADORES, TIPOS E DOMNIOS

    Criando um dominio de dados para CPF e um operadorunrio que o valida:

    BEGIN;DROP SCHEMA IF EXISTS teste CASCADE;CREATE SCHEMA teste;SET search_path TO teste;

    CREATE OR REPLACE FUNCTION cpf_valido(numeric)RETURNS BOOLEAN LANGUAGE SQLCOST 10IMMUTABLE STRICTAS $_$ with cpf as ( select $1 as numero ), cpf_formatado as ( select lpad(cpf.numero::text,11,'0') as numero from cpf ), matriz as ( select regexp_split_to_table( cpf_formatado.numero, E'\\s*' ) as valor from cpf_formatado ), digitos_por_posicao_1 as ( select row_number() over () as posicao, valor::int

  • select row_number() over () as posicao, valor::int from matriz ),

    digitos_por_posicao_2 as ( select posicao - 1 as posicao, valor from digitos_por_posicao_1 ), digito_1 as ( select sum(posicao*valor) as soma, sum(posicao*valor) % 11 as resto from digitos_por_posicao_1 where posicao

  • );

    CREATE DOMAIN cpf AS numeric CHECK ( cpf_valido(VALUE) );COMMIT;

    E agora testar para ver como funcionaSET search_path TO teste;DROP TABLE IF EXISTS teste.pessoa;

    SELECT cpf_valido(59328253241);

    SELECT 59328253241 #? AS cpf_valido;SELECT 37821042773 #? AS cpf_valido;SELECT 91416742433 #? AS cpf_valido;SELECT 91416000433 #? AS cpf_valido;SELECT 37821042003 #? AS cpf_valido;SELECT NOT 37821042003 #? AS cpf_valido;SELECT NOT 91416000433 #? AS cpf_valido;

    CREATE TABLE teste.pessoa ( nro_cpf cpf);

    INSERT INTO teste.pessoa VALUES(88229346798);INSERT INTO teste.pessoa VALUES(45476684425);

    E se eu tentar inserir CPF INVALIDO!?INSERT INTO pessoa VALUES(45076684425);INSERT INTO pessoa VALUES(81249396798);

  • VIA C#include "postgres.h"#include #include "fmgr.h"#include "utils/geo_decls.h"

    #ifdef PG_MODULE_MAGICPG_MODULE_MAGIC;#endif

    PG_FUNCTION_INFO_V1(makepoint);Datummakepoint(PG_FUNCTION_ARGS){ /* Here, the pass-by-reference nature of Point is not hidden. */ Point *pointx = PG_GETARG_POINT_P(0); Point *pointy = PG_GETARG_POINT_P(1); Point *new_point = (Point *) palloc(sizeof(Point));

    new_point->x = pointx->x; new_point->y = pointy->y;

    PG_RETURN_POINT_P(new_point);}

    E para o SQL reconhecer esta funo, preciso cri-la em meubanco.

    CREATE FUNCTION makepoint(point, point) RETURNS point AS 'DIRECTORY/funcs', 'makepoint' LANGUAGE C STRICT;

  • VIA LINGUAGEM_DO_SEU_CORACAO

    Criar a linguagem utilizando extenso:create extension if not exists plpython2u;

    create or replace function array_transpose(a float[]) returns float[]language plpython2uas $$

    import numpy as np

    return np.array(a).transpose()

    $$;

    E usar ela no SQL:select array_transpose(array[1.0, 2.0, 4.5]);

    Mas com algumas limitaes, as vezes:select array_transpose(array[ array[1.0, 2.0], array[4.5, 7.8]]);

  • ERRO: no pode converter matrizmultidimensional para lista python detalhe:

    pl/python s suporta matrizesunidimensionais. contexto: funo pl/python

    "array_transpose"/

  • REPOSITRIO DE EXTENSES

  • PYPI

    pip search pip install

  • PGXN CLIENT

    pgxn search pgxn install

  • INTEROPERABILIDADE

  • LIBPQasync non-blockstream (controle de uxo)text/binarynoticaes assncronas (LISTEN/NOTIFY)COPY (trasferncia de dados)

  • PSYCOPG2Exemplo bsico de execuo:

    import psycopg2

    dbconn = psycopg2.connect(host="/var/run/postgresql", dbname="guedes")cursor = dbconn.cursor()

    cursor.execute("""SELECT relnameFROM pg_classWHERE relkind='r'""")

    for row in cursor.fetchall(): print("Tabela: {}".format(row[0]))

    cursor.close()dbconn.close()

    http://initd.org/psycopg/docs/index.html

  • implementado em C, como wrapper da libpqnoticaesCOPY

    criao de tipo personalizados

    equivalencia de tipos Python vs PostgreSQL

    from psycopg2.extensions import adapt, register_adapter, AsIs class Point(object): def __init__(self, x, y): self.x = x self.y = y def adapt_point(point): x = adapt(point.x).getquoted() y = adapt(point.y).getquoted() return AsIs("'(%s, %s)'" % (x, y)) register_adapter(Point, adapt_point) cur.execute("INSERT INTO atable (apoint) VALUES (%s)", (Point(1.23, 4.56),))

    INSERT INTO atable (apoint) VALUES ('(1.23, 4.56)');

    http://initd.org/psycopg/docs/usage.html#python-types-adaptation

  • CURIOSIDADEA biblioteca psycopg2 e o cliente de linha de comando pgxn

    so de autoria de Daniele Varrazzo

  • :|respirem

  • "O POSTGRS"Costumamos falar em "um cdigo Pythnico" mas e com

    SQL?

  • O ANINHADOR FRENTICO

  • PROBLEMASELECT ..., CASE WHEN sobrenome IS NULL THEN nome WHEN sobrenome IS NOT NULL THEN sobrenome || ',' || nome ENDFROM ...

  • SOLUODai voc vai l e mostra como faz

    SELECT ..., COALESCE(sobrenome || ',', '') || nomeFROM ...

  • O ANINHADOR FRENTICO II

  • PROBLEMASELECT ..., CASE WHEN COALESCE(endereco, '') '' THEN CASE WHEN COALESCE( COALESCE(endereco, '') || ' ' || COALESCE(bairro, '') ) ' ' THEN endereco ||' '|| bairro ELSE COALESCE(cidade, '') END ELSE COALESCE(cidade,'SEM CIDADE') ENDFROM ...LEFT JOIN ...LEFT JOIN ...

  • POSSVEL SOLUOSELECT ..., COALESCE(endereco ||' '|| bairro, cidade, 'SEM CIDADE'),FROM ...LEFT JOIN ...LEFT JOIN ...

  • OPA! TRS PARMETROS?SELECT ..., COALESCE(endereco ||' '|| bairro, cidade, 'SEM CIDADE'), ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ ^^^^^^^^^^FROM ...LEFT JOIN ...LEFT JOIN ...

  • QUAL O RESULTADO DISTO?SELECT ..., COALESCE(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'SEM VALOR'), COALESCE(NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'SEM VALOR'), COALESCE(NULL, NULL, NULL, NULL, NULL, NULL, 'SEM VALOR'), COALESCE(NULL, NULL, NULL, NULL, NULL, 'SEM VALOR'), COALESCE(NULL, NULL, NUL