CONHEÇA AS FORMAÇÕES EXCLUSIVAS DO CODANDO BRASIL!

ACESSAR AGORA!

Como validar CSV com Python: tutorial com código completo

JUNTE-SE Á NOSSA LISTA VIP!

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

100% livre de spam.

Compartilhe agora mesmo:

Aprenda a validar arquivos CSV com Python, identificar preços inválidos, campos vazios e registros duplicados, com código completo e exemplos práticos.

Você recebe uma planilha de vendas, exporta os dados e começa a importar o arquivo para outro sistema. Tudo parece funcionar até descobrir que um preço veio vazio, um produto apareceu duas vezes e uma coluna mudou de nome. A automação terminou sem reclamar, mas o relatório ficou errado. É justamente nessa situação que validar CSV com Python deixa de ser um exercício de programação e passa a resolver um problema real.

Neste tutorial, você vai construir um validador para um catálogo de produtos. Ele verifica a estrutura do arquivo, identifica registros inconsistentes e produz um relatório que permite corrigir os dados na origem. O exemplo utiliza a biblioteca padrão do Python, sem exigir pandas ou acesso a serviços externos. Assim, você consegue entender cada decisão antes de acrescentar ferramentas mais sofisticadas.

O objetivo é terminar com algo que você consiga executar, explicar e adaptar. Além do código, vamos discutir delimitadores, valores monetários, duplicidade, mensagens de erro e limites da solução. Se você ainda está conhecendo a linguagem, leia também nosso artigo sobre o que é Python e suas aplicações. Depois, volte para transformar a teoria em uma pequena ferramenta de trabalho.

Validação antes da importação
01Contrato
Defina colunas, delimitador, codificação e regras.
02Conferência
Verifique estrutura e valores sem sobrescrever o original.
03Decisão
Siga somente com os dados aprovados; relate os erros.

O que significa validar um arquivo CSV?

CSV é um formato textual usado para representar dados em linhas e campos. Apesar do nome, os campos não precisam ser separados apenas por vírgulas: o ponto e vírgula é comum em exportações brasileiras. A primeira linha frequentemente contém os nomes das colunas, e as demais representam registros. Essa simplicidade facilita a integração entre sistemas, mas também permite que arquivos visualmente parecidos carreguem significados diferentes.

Validar significa comparar o arquivo com regras explícitas. No nosso catálogo, cada registro precisa ter um identificador inteiro positivo, um nome preenchido e um preço maior que zero. O identificador também não pode se repetir. Essas regras não são universais: um sistema que trabalha com brindes pode aceitar preço zero, enquanto outro pode permitir identificadores alfanuméricos. A regra correta nasce da finalidade dos dados.

Também precisamos separar três perguntas. O arquivo pode ser aberto? Sua estrutura corresponde ao contrato esperado? Os valores atendem às regras do negócio? Um CSV pode passar nas duas primeiras etapas e falhar na terceira. A existência de uma coluna chamada preço não comprova que todas as células contenham preços válidos. O computador faz o que programamos; infelizmente, ele não adivinha o combinado na reunião.

Defina o contrato antes de escrever o código

Para este projeto, vamos exigir exatamente três colunas, nesta ordem: id, nome e preco. Usaremos ponto e vírgula como delimitador e UTF-8 como codificação. O preço aceitará ponto ou vírgula como separador decimal, sem separador de milhares. Exemplos aceitos são 19.90 e 19,90; a sequência 1.299,90 será rejeitada.

Essa escolha evita uma conversão silenciosa perigosa. Remover todos os pontos e substituir vírgulas pode funcionar em um arquivo e distorcer outro. Quando o formato não está claro, rejeitar o valor com uma orientação útil é melhor do que inventar sua interpretação. Quem exporta os dados deve conhecer o contrato, e quem importa deve aplicá-lo de forma previsível.

Nosso programa vai relatar todos os problemas encontrados nos registros legíveis, sem importar automaticamente nenhum deles. Se houver um erro, retornará um código de saída diferente de zero. Isso permite que outra automação interrompa a sequência. Para o exemplo inicial, o relatório vai para o terminal; mais adiante, você poderá gravá-lo em um arquivo separado ou encaminhá-lo a uma interface administrativa.

Prepare o ambiente e os arquivos de exemplo

Você precisa de Python 3.10 ou superior e de um editor de texto. Crie uma pasta para o projeto e mantenha os exemplos separados de qualquer arquivo real da empresa. Trabalhar com dados fictícios facilita o aprendizado e evita que um teste gere uma alteração indevida. No Linux, você pode usar os comandos abaixo. Em outros sistemas, o comando do interpretador pode ser python ou py.

mkdir validador-csv
cd validador-csv
python3 --version

Se criar diretórios pelo terminal ainda é novidade, consulte nosso tutorial do comando mkdir. Para navegar entre pastas, há também o material sobre o comando cd. São detalhes pequenos que ajudam a entender onde o programa procura seus arquivos e onde você realmente está trabalhando.

Salve este conteúdo como produtos-validos.csv. Use um editor que permita escolher UTF-8 ao salvar:

id;nome;preco
1;Teclado;149,90
2;Mouse;79.50
3;Monitor;899.00

Crie também produtos-invalidos.csv:

id;nome;preco
1;Teclado;149,90
1;Mouse;79.50
3;;899.00
4;Cabo;gratis
5;Adaptador;-12.00

Esse segundo arquivo contém problemas diferentes de propósito. O registro duplicado testa identidade; o nome vazio testa preenchimento; a palavra no preço testa conversão; e o número negativo testa uma regra comercial. Separar os tipos de problema ajuda a perceber que uma única verificação, como tentar converter um número, não cobre o processo inteiro.

Leia CSV com uma ferramenta própria para CSV

É tentador abrir cada linha e usar split(';'). Entretanto, um nome pode conter o próprio delimitador dentro de aspas, e um campo pode conter uma quebra de linha. Usar o módulo csv permite respeitar essas convenções. No exemplo, DictReader associa os valores aos nomes do cabeçalho, tornando a regra de validação mais legível.

O arquivo será aberto com newline='' para que o leitor CSV gerencie as quebras de linha. A codificação utf-8-sig permite ler UTF-8 com ou sem a marca BOM, que pode aparecer em arquivos exportados por planilhas. Isso resolve esse caso específico; não significa que qualquer codificação será reconhecida automaticamente. Um arquivo em outra codificação precisa de conversão ou de um contrato diferente.

O modo estrito ajuda a detectar certas inconsistências de aspas e sintaxe, mas não substitui as nossas regras de estrutura. Por isso, verificaremos campos extras e campos ausentes. Em DictReader, uma linha maior do que o cabeçalho pode gerar uma chave None, enquanto uma linha menor pode produzir valores ausentes. Essas situações precisam ser tratadas conscientemente.

Regras do catálogo de exemplo
Campo / estruturaRegra
CabeçalhoExatamente id;nome;preco, nessa ordem.
idInteiro positivo, sem repetição após conversão.
nomePreenchido após remover espaços externos.
precoMaior que zero; ponto ou vírgula decimal, sem milhares.
ArquivoUTF-8, delimitador ; e pelo menos um produto.

Código completo do validador

Salve o código abaixo em validar_csv.py. Ele organiza a leitura e a validação em uma função e deixa a interação com o terminal no ponto de entrada. O uso de Decimal permite representar os preços decimais sem depender da aproximação binária típica de float. Ainda precisamos decidir regras de arredondamento em aplicações comerciais; neste catálogo, apenas verificamos o formato e o valor.

import argparse
import csv
import re
import sys
from decimal import Decimal, InvalidOperation
from pathlib import Path

COLUNAS = ['id', 'nome', 'preco']
FORMATO_PRECO = re.compile(r'^[0-9]+([.,][0-9]{1,2})?$')


def validar(arquivo: Path) -> tuple[int, list[str]]:
    erros: list[str] = []
    ids: set[int] = set()
    total = 0

    with arquivo.open(encoding='utf-8-sig', newline='') as entrada:
        leitor = csv.DictReader(entrada, delimiter=';', strict=True)

        if leitor.fieldnames != COLUNAS:
            return 0, ['Cabeçalho inválido: esperado id;nome;preco.']

        for registro, linha in enumerate(leitor, start=1):
            total += 1
            referencia = f'Registro {registro} (linha final {leitor.line_num})'

            if None in linha or any(linha[c] is None for c in COLUNAS):
                erros.append(f'{referencia}: quantidade incorreta de campos.')
                continue

            texto_id = linha['id'].strip()
            nome = linha['nome'].strip()
            texto_preco = linha['preco'].strip()

            if not re.fullmatch(r'[0-9]+', texto_id):
                erros.append(f'{referencia}: id deve ser inteiro positivo.')
            else:
                identificador = int(texto_id)
                if identificador <= 0:
                    erros.append(f'{referencia}: id deve ser maior que zero.')
                elif identificador in ids:
                    erros.append(f'{referencia}: id duplicado ({identificador}).')
                else:
                    ids.add(identificador)

            if not nome:
                erros.append(f'{referencia}: nome não pode estar vazio.')

            if not FORMATO_PRECO.fullmatch(texto_preco):
                erros.append(
                    f'{referencia}: preço inválido; use 19.90 ou 19,90, '
                    'sem separador de milhares.'
                )
            else:
                try:
                    preco = Decimal(texto_preco.replace(',', '.'))
                except InvalidOperation:
                    erros.append(f'{referencia}: preço não reconhecido.')
                else:
                    if preco <= 0:
                        erros.append(f'{referencia}: preço deve ser maior que zero.')

    if total == 0:
        erros.append('O arquivo precisa conter pelo menos um produto.')

    return total, erros


def main() -> int:
    parser = argparse.ArgumentParser(description='Valida catálogo CSV.')
    parser.add_argument('arquivo', type=Path)
    argumentos = parser.parse_args()

    try:
        total, erros = validar(argumentos.arquivo)
    except (OSError, UnicodeError, csv.Error) as erro:
        print(f'Não foi possível ler o arquivo: {erro}', file=sys.stderr)
        return 2

    if erros:
        print(f'Arquivo rejeitado: {total} registro(s), {len(erros)} erro(s).')
        for erro in erros:
            print(f'- {erro}')
        return 1

    print(f'Arquivo válido: {total} produto(s) conferido(s).')
    return 0


if __name__ == '__main__':
    raise SystemExit(main())

Execute e interprete o resultado

Abra o terminal dentro da pasta do projeto e execute:

python3 validar_csv.py produtos-validos.csv
python3 validar_csv.py produtos-invalidos.csv

O primeiro comando deve informar que três produtos foram conferidos. O segundo deve rejeitar o arquivo, apresentando quatro problemas: identificador duplicado, nome vazio e dois preços em formato inválido. O preço negativo é rejeitado pelo contrato de formato, que não aceita sinal. Já um preço 0.00 passa pelo formato, mas é rejeitado pela regra de valor maior que zero.

Essa distinção ajuda a investigar um comportamento aparentemente estranho. Uma regra verifica como o dado está escrito; outra verifica o que ele significa para o sistema. Quando você muda o contrato para aceitar preços negativos, precisa revisar as duas etapas. Alterar apenas a expressão regular permitiria a conversão, mas a regra de valor continuaria impedindo o registro.

O número de erros não precisa ser igual ao número de registros ruins. Uma única linha pode ter nome vazio e preço inválido, gerando duas mensagens. Por isso, o resumo usa contagem de erros, sem anunciar uma quantidade imprecisa de produtos rejeitados. Também identificamos o registro lógico e sua linha física final: campos entre aspas podem ocupar várias linhas no arquivo.

Teste situações que costumam escapar

Agora modifique um exemplo por vez e observe a mensagem. Troque o cabeçalho para ID;nome;preco; retire uma coluna; adicione um campo extra; deixe o arquivo apenas com o cabeçalho. Todas essas alterações devem ser rejeitadas. Depois, coloque espaços antes e depois do nome: o programa aceita o registro porque retira os espaços externos antes de verificar o preenchimento.

Experimente usar os identificadores 1 e 01. Como ambos viram o inteiro um, serão considerados duplicados. Essa é uma decisão deliberada. Se zeros à esquerda fizerem parte de um código comercial, o identificador deve permanecer texto, e as regras precisam mudar. Um validador só pode ser considerado correto quando respeita o significado das informações que está processando.

Teste também um nome com ponto e vírgula: 6;"Kit; edição especial";49.90. As aspas mantêm o delimitador dentro do campo, e o leitor consegue interpretar o registro. Você pode adicionar um nome com acentuação para conferir a codificação. Evite avaliar a ferramenta somente com dados perfeitos; os casos inconvenientes são justamente aqueles que justificam sua existência.

Como conectar a validação a uma importação

Quando o catálogo precisar alimentar um banco de dados, execute a validação antes da escrita. Em um processo pequeno, você pode ler novamente o arquivo aprovado e importar seus registros. Entretanto, garanta que o conteúdo não mudou entre as duas leituras. Uma alternativa é copiar a entrada para uma área de processamento ou verificar uma identificação do arquivo antes de seguir.

A gravação deve acontecer dentro de uma transação quando o banco e o caso de uso permitirem. Assim, uma falha não deixa metade do catálogo atualizado e metade pendente. O banco também precisa ter restrições próprias, como uma chave única para o identificador. A validação melhora as mensagens e antecipa problemas; as restrições persistentes protegem os dados contra outros caminhos de entrada.

Para conhecer os conceitos de consulta e organização relacional, consulte nossa introdução ao SQL. Ao implementar consultas, forneça valores por parâmetros, em vez de concatenar texto recebido do arquivo dentro da instrução. Um produto válido para o catálogo continua sendo um dado externo, e seu nome nunca deve virar parte executável de uma consulta.

Limites do exemplo e melhorias úteis

Este programa foi pensado para arquivos locais e catálogos pequenos ou médios. Ele percorre os registros sequencialmente, mas mantém todos os identificadores e todas as mensagens em memória. Em um arquivo muito grande, essas estruturas podem crescer bastante. Você pode limitar a quantidade de erros exibidos, gerar um relatório incremental ou usar uma estratégia de armazenamento adequada ao volume.

Também não existe limite para o tamanho do nome no exemplo. Um sistema real deve definir essa regra com base no destino: se a coluna do banco aceita cem caracteres, o validador precisa identificar nomes maiores antes de gravar. Outras regras possíveis incluem categorias permitidas, códigos obrigatórios e correspondência entre fornecedores. Acrescente cada regra porque há uma necessidade concreta, sem transformar um catálogo simples em um tribunal burocrático.

Se o CSV vier de usuários pela internet, você precisará acrescentar limites de tamanho, controle de acesso e tratamento seguro de arquivos. Esses recursos pertencem à aplicação que recebe o envio. Para exportar dados novamente a uma planilha, considere também que certos valores podem ser interpretados como fórmulas. Validar o conteúdo de entrada e preparar uma saída para outro programa são responsabilidades diferentes.

Aprenda expressões regulares com um objetivo concreto

No código, as expressões regulares descrevem dois formatos curtos: identificadores numéricos e preços decimais. Elas ajudam quando a pergunta é sobre uma sequência de caracteres. Já a duplicidade exige memória sobre outros registros, e o valor positivo exige uma comparação numérica. Saber escolher a ferramenta evita expressões enormes que tentam resolver tudo ao mesmo tempo.

Se você deseja aprofundar essa parte, o Codando Brasil recomenda o Curso de Expressões Regulares de Julio Cezar Neves em sua página inicial. Consulte a página da oferta para conferir programa, condições e disponibilidade antes de decidir. É uma opção relacionada ao que usamos aqui, especialmente se seu trabalho envolve encontrar padrões e tratar textos.

Transparência: este é um link de afiliado. Uma compra realizada por ele pode gerar comissão para o Codando Brasil.

Perguntas frequentes sobre validar CSV com Python

Preciso instalar pandas para seguir este tutorial?

Não. O exemplo usa apenas módulos da biblioteca padrão. Pandas pode ser interessante quando você precisa de análises tabulares e transformações mais amplas, mas não é necessário para verificar esse catálogo. Começar com ferramentas menores torna o fluxo fácil de acompanhar e reduz a quantidade de dependências que você precisa administrar.

O validador corrige automaticamente os dados?

Não. Ele retira espaços externos para interpretar os campos, mas não sobrescreve o CSV. A saída explica o que precisa de revisão. Separar validação e correção preserva o arquivo original e evita alterações que poderiam mudar o significado dos registros. Se criar uma etapa de correção, grave outro arquivo e documente as mudanças aplicadas.

Posso aceitar outro delimitador?

Sim, desde que você altere o argumento do leitor e o contrato documentado. Se trocar para vírgula, um preço escrito com vírgula decimal precisará ser corretamente delimitado por aspas. Não altere o leitor sozinho e mantenha instruções antigas: dados, exemplos e mensagens devem continuar descrevendo o mesmo formato.

Como saber se o arquivo passou na validação?

Além da mensagem, o processo retorna zero em caso de sucesso, um para falhas nas regras e dois para falhas de leitura. No Bash, execute echo $? imediatamente depois do programa para consultar esse código. Outra aplicação pode usar o retorno para decidir se continua a importação, sem depender de interpretar uma frase no terminal.

Seu próximo passo: transforme o exemplo em uma ferramenta sua

Escolha um arquivo que faça parte da sua rotina e escreva suas regras em linguagem simples antes de modificar o programa. Liste os campos, os valores permitidos, os exemplos aceitos e as situações rejeitadas. Depois, implemente uma regra por vez e mantenha um conjunto pequeno de arquivos de teste. Isso torna cada alteração verificável e facilita explicar a ferramenta para outras pessoas.

Você pode evoluir o projeto para gerar relatórios, validar exportações de uma loja ou conferir dados antes de alimentar um dashboard. O resultado mais interessante não é a quantidade de linhas de código: é conseguir reduzir um erro recorrente com um processo compreensível. Compartilhe nos comentários qual tipo de CSV você precisa conferir e quais regras tornam esse arquivo útil no seu trabalho.

Documentação para continuar estudando

Compartilhe agora mesmo:

Você vai gostar também:

Para enviar seu comentário, preencha os campos abaixo:

Deixe um comentário


*


*


Seja o primeiro a comentar!

JUNTE-SE Á NOSSA LISTA VIP!

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

100% livre de spam.

Damos valor à sua privacidade

Nós e os nossos parceiros armazenamos ou acedemos a informações dos dispositivos, tais como cookies, e processamos dados pessoais, tais como identificadores exclusivos e informações padrão enviadas pelos dispositivos, para as finalidades descritas abaixo. Poderá clicar para consentir o processamento por nossa parte e pela parte dos nossos parceiros para tais finalidades. Em alternativa, poderá clicar para recusar o consentimento, ou aceder a informações mais pormenorizadas e alterar as suas preferências antes de dar consentimento. As suas preferências serão aplicadas apenas a este website.

Cookies estritamente necessários

Estes cookies são necessários para que o website funcione e não podem ser desligados nos nossos sistemas. Normalmente, eles só são configurados em resposta a ações levadas a cabo por si e que correspondem a uma solicitação de serviços, tais como definir as suas preferências de privacidade, iniciar sessão ou preencher formulários. Pode configurar o seu navegador para bloquear ou alertá-lo(a) sobre esses cookies, mas algumas partes do website não funcionarão. Estes cookies não armazenam qualquer informação pessoal identificável.

Cookies de desempenho

Estes cookies permitem-nos contar visitas e fontes de tráfego, para que possamos medir e melhorar o desempenho do nosso website. Eles ajudam-nos a saber quais são as páginas mais e menos populares e a ver como os visitantes se movimentam pelo website. Todas as informações recolhidas por estes cookies são agregadas e, por conseguinte, anónimas. Se não permitir estes cookies, não saberemos quando visitou o nosso site.

Cookies de funcionalidade

Estes cookies permitem que o site forneça uma funcionalidade e personalização melhoradas. Podem ser estabelecidos por nós ou por fornecedores externos cujos serviços adicionámos às nossas páginas. Se não permitir estes cookies algumas destas funcionalidades, ou mesmo todas, podem não atuar corretamente.

Cookies de publicidade

Estes cookies podem ser estabelecidos através do nosso site pelos nossos parceiros de publicidade. Podem ser usados por essas empresas para construir um perfil sobre os seus interesses e mostrar-lhe anúncios relevantes em outros websites. Eles não armazenam diretamente informações pessoais, mas são baseados na identificação exclusiva do seu navegador e dispositivo de internet. Se não permitir estes cookies, terá menos publicidade direcionada.

Visite as nossas páginas de Políticas de privacidade e Termos e condições.