7.3.5. Criando Funções

Nessa seção, vamos reescrever algumas das funções PL/pgSQL criadas na Seção 7.1.


Geração de um conjunto de pontos aleatórios:

CREATE OR REPLACE FUNCTION py_random_pt_generator(npts INTEGER)
    RETURNS SETOF RECORD
    AS
    $$
        from random import random
        from shapely import wkb
        from shapely.geometry import Point

        plpy.notice('Computando {} pontos aleatórios...'.format(npts))

        for i in range(1, npts + 1):
            longitude = 360.0 * random() - 180.0
            latitude = 180.0 * random() - 90.0

            pt = Point(longitude, latitude)

            tupla = ( i, wkb.dumps(pt, 'hex') )

            if i % 1000 == 0:
                plpy.notice('py_random_pt_generator: iteração {}'.format(i))

            yield(tupla)

        plpy.notice('Finalizado!')
    $$
    LANGUAGE plpython3u;

Para chamar a função acima teremos que realizar um CAST da geometria para definir o SRID:

SELECT gid, ST_AsEWKT(geom)
  FROM py_random_pt_generator(5) AS tabela(gid integer, geom geometry(point, 4326));

Criando uma função que cria uma tabela com um certo número de linhas:

CREATE OR REPLACE FUNCTION py_build_pt_table(table_name TEXT, npts INTEGER)
    RETURNS VOID
    AS
    $$
        plpy.notice('Criando tabela {}...'.format(table_name))
        cmd_create = 'CREATE TABLE {} (gid INTEGER, geom GEOMETRY(POINT,4326))'.format(table_name)
        plpy.execute(cmd_create)

        query_pts = 'SELECT * FROM py_random_pt_generator({}) AS tabela(gid INTEGER, geom GEOMETRY(POINT, 4326))'.format(npts)

        cmd_insert = 'INSERT INTO {} (gid, geom) VALUES($1, $2)'.format(table_name)
        prepared_insert = plpy.prepare(cmd_insert, ['INTEGER', 'GEOMETRY'])

        for tupla in plpy.cursor(query_pts):
            plpy.execute(prepared_insert, [tupla['gid'], tupla['geom']])

        plpy.notice('Criando chave primária...')
        plpy.execute('ALTER TABLE {} ADD PRIMARY KEY(gid)'.format(table_name))

        plpy.notice('Criando índice espacial...')
        plpy.execute('CREATE INDEX {0}_geom_idx ON {0} USING GIST (geom)'.format(table_name))
    $$
    LANGUAGE plpython3u;

Para chamar a função acima, faça:

SELECT py_build_pt_table('pt10k_v2', 10000);