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.