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