-
Notifications
You must be signed in to change notification settings - Fork 0
Upload e integridade dos dados originais
A seguir passo a passo didático que deu origem ao algoritmo "automatizador de ingestão".
Os arquivos precisam ser distribuídos, via FTP ou SFTP, por pastas do município.
Por exemplo, com ls /home/igor/ obtemos a listagem das pastas organizadas pelo Igor em junho de 2020:
BR-ES-Serra BR-PR-Cascavel BR-RS-PortoAlegre BR-SP-LaranjalPaulista BR-SP-SaoVicente
BR-ES-VilaVelha BR-PR-Pinhais BR-RS-SantaMaria BR-SP-Osasco BR-SP-Sorocaba
BR-ES-Vitoria BR-PR-SaoJosePinhais BR-SC-JaraguaSul BR-SP-Santos
BR-MG-BeloHorizonte BR-RJ-Niteroi BR-SP-Itu BR-SP-SaoBernardoCampo
BR-PE-Recife BR-RS-Gravatai BR-SP-Jundiai BR-SP-SaoPaulo
Dentro de cada uma delas são mantidos os arquivos de input. Por exemplo:
ls /home/igor/BR-RS-PortoAlegre/input
# SMF-XLSX-ORIGINAIS.zipOs arquivos de carga podem ser verificados diretamente pelo PostgreSQL, conforme a função ingest.cityfolder_input_files definida abaixo
CREATE or replace FUNCTION ingest.cityfolder_input_files(
p_fpath text DEFAULT '/tmp/pg_io/'
) RETURNS TABLE (fid int, cityname text, fname text, is_validext boolean, fmeta jsonb) AS $f$
WITH t0 AS ( SELECT rtrim(p_fpath,'/') AS fpath )
, t1 AS (
SELECT f as cityname,
t0.fpath ||'/'|| f as f
FROM pg_ls_dir((SELECT fpath FROM t0)) t(f), t0
WHERE f ~ '^BR\-[A-Z]{2,2}\-[A-Za-z]+$'
)
SELECT (row_number() OVER ())::int id,
cityname, fname,
fname ~* '\.(zip|gz|rar|geojson|csv|dwg)$' as is_validext,
to_jsonb( pg_stat_file(fpath||'/'||fname) ) || jsonb_build_object('fpath',fpath)
FROM (
SELECT cityname,
f||'/'||'input' as fpath,
pg_ls_dir(f||'/'||'input') as fname
FROM t1
ORDER BY 1,3
) t2
$f$ LANGUAGE SQL IMMUTABLE;
-- Exemplo:
SELECT cityname, fname, is_validext, fmeta->>'size' as bytes
FROM ingest.cityfolder_input_files('/home/igor');No exemplo, rodando em 1 de julho de 2020, foram listados 243 arquivos válidos:
| cityname | fname | is_validext | bytes |
|---|---|---|---|
| BR-ES-Serra | 2018-01-05 BaseCartográfica.gdb.zip | t | 24218623 |
| BR-ES-VilaVelha | BAIRROS.zip | t | 68069 |
| BR-ES-VilaVelha | LOTES.zip | t | 6282461 |
| BR-ES-VilaVelha | QUADRAS.zip | t | 2327148 |
| ... | ... | ... | ... |
| BR-SP-SaoPaulo | SIRGAS_SHP_quadraviariaed.zip | t | 70291605 |
| BR-SP-SaoPaulo | SIRGAS_SHP_subprefeitura.zip | t | 1188797 |
| BR-SP-SaoVicente | MAPA DE LOTEAMENTOS.dwg | t | 22665728 |
| BR-SP-Sorocaba | lotes_prediais.zip | t | 14476669 |
| BR-SP-Sorocaba | shape_eixos_sorocaba.zip | t | 1880173 |
RESUMO DOS ARQUIVOS VÁLIDOS POR MUNICÍPIO:
SELECT cityname, COUNT(*) as n_files,
sum(bytes/1048576) as "tot MiB",
ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY bytes) /1048576 ) as "median MiB"
FROM (
SELECT cityname, (fmeta->'size')::int as bytes
FROM ingest.cityfolder_input_files('/home/igor')
WHERE is_validExt
) t
GROUP BY 1;| cityname | n_files | tot MiB | median MiB |
|---|---|---|---|
| BR-ES-Serra | 1 | 23 | 23 |
| BR-ES-VilaVelha | 4 | 10 | 3 |
| BR-ES-Vitoria | 4 | 16 | 4 |
| BR-MG-BeloHorizonte | 1 | 40 | 41 |
| BR-PE-Recife | 1 | 26 | 27 |
| BR-PR-Cascavel | 3 | 10 | 2 |
| ... | .. | .. | .. |
| BR-SP-SaoBernardoCampo | 5 | 38 | 3 |
| BR-SP-SaoPaulo | 197 | 1013 | 3 |
| BR-SP-SaoVicente | 1 | 21 | 22 |
| BR-SP-Sorocaba | 2 | 14 | 8 |
GERANDO LINHAS DE COMANDO PARA RENOMEAR:
SELECT 'sha256sum "'|| f ||'"'
FROM (
SELECT fmeta->>'fpath' as fpath, fmeta->>'fpath' ||'/'|| fname as f
FROM ingest.cityfolder_input_files('/home/igor')
WHERE is_validExt
) t
;Amostra dos resultados, e execução como comandos e respectivos resultados:
sha256sum "/home/igor/BR-ES-Serra/input/2018-01-05 BaseCartográfica.gdb.zip"
# b18fc8ebe8bccc2cfdbbbd5f4896d5f6573033ebfa80061d1d86550c5ae8521d /home/igor/BR-ES-Serra/input/2018-01-05 BaseCartográfica.gdb.zip
sha256sum "/home/igor/BR-ES-VilaVelha/input/BAIRROS.zip"
# c0cd7b2a4cc67b5d49a4d296f41b564b23464364ab746adc6d2206d5dd9249af /home/igor/BR-ES-VilaVelha/input/BAIRROS.zipPode-se portanto criar uma função shell que já execute também o mv, por exemplo
mv "/home/igor/BR-ES-Serra/input/2018-01-05 BaseCartográfica.gdb.zip" b18fc8ebe8bccc2cfdbbbd5f4896d5f6573033ebfa80061d1d86550c5ae8521d.zip
mv "/home/igor/BR-ES-VilaVelha/input/BAIRROS.zip" c0cd7b2a4cc67b5d49a4d296f41b564b23464364ab746adc6d2206d5dd9249af.zipA cada município a pasta {municipio}/input designa pode conter ou arquivos padrão ou subpastas de arquivos mais especificos.
Os tipos respeitam a sintaxe ... E cada um dos tipos ("content type" ou simplesmente ctype) e scripts de tratamento são descritos na planilha... Para destacar esses tipos a função então foi redefinida como se segue:
CREATE or replace FUNCTION ingest.cityfolder_input_files(
p_fpath text DEFAULT '/tmp/pg_io/'
) RETURNS TABLE (fid int, cityname text, fname text, ctype text, is_validext boolean, fmeta jsonb) AS $f$
WITH t0 AS ( SELECT rtrim(p_fpath,'/') AS fpath )
, t1 AS (
SELECT f as cityname,
t0.fpath ||'/'|| f as f
FROM pg_ls_dir((SELECT fpath FROM t0)) t(f), t0
WHERE f ~ '^BR\-[A-Z]{2,2}\-[A-Za-z]+$'
)
,tres AS (
SELECT cityname, fname, 'std' AS ctype,
to_jsonb( pg_stat_file(fpath||'/'||fname) ) || jsonb_build_object('fpath',fpath) fmeta
FROM ( -- t2:
SELECT cityname,
f||'/'||'input' as fpath,
pg_ls_dir(f||'/'||'input') as fname
FROM t1
ORDER BY 1,3
) t2
)
SELECT (row_number() OVER ())::int id,
cityname , fname, ctype,
fname ~* '\.(zip|gz|rar|geojson|csv|dwg)$' as is_validext,
fmeta
FROM ( -- t3:
SELECT * FROM tres WHERE not((fmeta->'isdir')::boolean)
UNION
SELECT cityname, fname,ctype,
to_jsonb( pg_stat_file(fpath||'/'||fname) ) || jsonb_build_object('fpath',fpath) AS fmeta
FROM ( -- t4:
select cityname, fname as ctype,
(fmeta->>'fpath')||'/'|| fname AS fpath,
pg_ls_dir((fmeta->>'fpath')||'/'||fname) AS fname
from tres
where (fmeta->'isdir')::boolean
) t4
) t3
$f$ LANGUAGE SQL IMMUTABLE;
-- TESTE:
select cityname, ctype, count(*) n from ingest.cityfolder_input_files('/home/igor') group by 1,2 order by 1,2;| cityname | ctype | n |
|---|---|---|
| BR-ES-Serra | std | 1 |
| BR-ES-VilaVelha | std | 4 |
| ... | ... | ... |
| BR-SP-SaoPaulo | edificacoes | 96 |
| BR-SP-SaoPaulo | eixos | 1 |
| BR-SP-SaoPaulo | lotes | 96 |
| BR-SP-SaoPaulo | planilhas | 1 |
| BR-SP-SaoPaulo | quadras | 1 |
| BR-SP-SaoPaulo | subdivisao | 2 |
| BR-SP-SaoVicente | std | 1 |
| ... | ... | ... |
(wiki temporária!)