Segue um exemplo de como fazer uma consulta em um banco de dados (BD), calcular a soma diária dos valores de uma coluna e gravar um arquivo com o valor. Escrito em python e com uma consulta usando SQL, contém vários elementos para estudo.
Primeiramente, script a seguir importa os módulos necessários, recebe três argumentos externos (tipo/grupo, data inicial e data final) e define o caminho (path) do script em execução. Depois, ele abre um arquivo com o nome e código dos pontos de um grupo para ler linha por linha (exceto a primeira). Cada linha é quebrada pelo caractere espaço de modo a formar um vetor para guarda o primeiro elemento (o código do ponto).
A query de consulta ao banco de dados PostgreSQL extrai ano, mês e dia da coluna “data” para salvar essas variáveis em colunas separadas. Além disso, os dados são agrupados (GROUP BY) por dias e ordenados cronologicamente. Desse modo, são somados todos os valores horários da coluna “variavel” dentro de um mesmo dia (SUM).
O resultado da consulta ao banco é guardado no vetor de vetores “valores” (cada dia tem cinco valores, e o vetor final tem tantos elementos quanto o número de dias). Foi incluída uma verificação do tamanho do vetor para saber se tem o número desejado de dias ou se o resultado está incompleto ou mesmo vazio.
import psycopg2
import psycopg2.extras
import os
import sys
tipo = sys.argv[1]
datai = sys.argv[2]
dataf = sys.argv[3]
path = os.path.dirname(os.path.realpath(__file__))
with open('%s/Arq_Entrada/%s_postos.txt' % (path, tipo)) as arq:
next(arq)
for linha in arq:
vetor = linha.strip().split(" ")
posto = vetor[0]
# Montar query
query = '''SELECT codigo, EXTRACT(YEAR FROM data) as year, EXTRACT(MONTH FROM data) as month, EXTRACT(DAY FROM data) as day, SUM(variavel)
FROM schema.table WHERE codigo = '%s' AND data BETWEEN '%s' AND '%s'
GROUP BY codigo, EXTRACT(DAY FROM data), EXTRACT(MONTH FROM data), EXTRACT(YEAR FROM data) ORDER BY year ASC, month ASC, day ASC;''' %(posto, datai, dataf)
#print(query)
# Executar query
conn = psycopg2.connect(host = "hostname", database = "db", user="usuario")
cursor = conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
cursor.execute(query)
valores = cursor.fetchall()
# Fechar ponteiro e conexão
cursor.close()
conn.close()
if len(valores) != 46:
print "Posto " + posto + " vazio ou incompleto!"
else:
print "Posto " + posto + " OK"
# Gravar arquivo com dados
with open('%s/Arq_Saida/Posto_%s.txt' % (path, posto), 'wb') as f:
f.write('codigo data valor\n')
for line in valores:
i = 0
for elemento in line:
if elemento == None:
line[i] = "-"
else:
line[i] = round(float(elemento),1)
i = i + 1
f.write("%08d %02d/%02d/%04d %s\n" %(int(line[0]),int(line[3]),int(line[2]),int(line[1]),str(line[4])))
#sys.exit("fim de teste")
Por fim, é gravado um arquivo de saída com o nome do ponto trabalhado (com cabeçalho), linha por linha. Em cada linha (um vetor), é feita uma verificação em cada elemento: se estiver vazio, grava um traço; caso contrário, arredonda o valor para uma casa decimal. O código (formatado para ter 8 dígitos), a data e o valor (já convertido para string) são gravados separados por espaço.




