Pular para o conteúdo principal

Importar um CSV bancário para o Beancount com o bea

Importe um CSV bancário para o seu razão Beancount com o bea: mapeie colunas, categorize com regras, visualize os lançamentos, revise duplicatas e então aplique-os.

Um CSV bancário comum não precisa de um importador Python. Mapeie suas colunas com --csv, nomeie a conta de origem com --account, categorize as linhas com --rules, depois pré-visualize e aplique as entradas com bea import.

Você precisa de um livro-razão existente. Se estiver começando um novo livro, siga o início rápido da CLI. Mantenha o extrato bancário original para que possa compará-lo com a pré-visualização.

1. Mapeie as colunas do CSV​

Salve este exemplo como statement.csv, depois execute os comandos abaixo no mesmo diretório:

Date,Payee,Narration,Amount
2026-08-02,Whole Foods,groceries,-20.00
2026-08-03,Shell,gas,-40.00
2026-08-04,Unknown Shop,mystery,-9.99

Os valores usam a convenção de sinal do banco: gastos são negativos e depósitos são positivos. A moeda padrão é a moeda operacional do livro-razão, então este arquivo não precisa de uma coluna de moeda. Coloque uma coluna de descrição bancária em narration e mantenha payee para o comerciante.

Crie o livro-razão e abra a subconta combustível usada abaixo:

bea --no-input init books --currency USD --date 2026-08-01 \
  --opening-balance "Assets:Checking 1000"
bea --file books/main.bean add open --date 2026-08-01 --account Expenses:Transport:Fuel -c USD

O modelo já abre Expenses:Groceries e as outras contas comuns. Ele não abre Expenses:Transport:Fuel, então o segundo comando a abre antes da importação. Opções globais como --file vão antes do subcomando.

2. Pré-visualize as entradas​

Salve estas regras de categorização como rules.toml, depois pré-visualize:

cat > rules.toml <<'EOF'
[[rule]]
match = "whole foods|trader joe|corner market"
account = "Expenses:Groceries"
 
[[rule]]
match = "shell|chevron|exxon"
account = "Expenses:Transport:Fuel"
EOF
bea --file books/main.bean import statement.csv --csv date=Date,amount=Amount,payee=Payee,narration=Narration --account Assets:Checking --rules rules.toml

As regras correspondem primeiro ao beneficiário, depois à narração, ignorando maiúsculas/minúsculas. A primeira regra que corresponder vence. Linhas para as quais não há regra correspondente são lançadas em Expenses:Uncategorized com a flag ! para revisão posterior. O produto guia de IMPORTAÇÃO documenta a referência completa do mapeamento, incluindo o par debit e credit, a coluna category e a leitura de cabeçalho --csv auto.

Nada é escrito no livro-razão ainda. A pré-visualização informa 3 ready, 0 exact duplicates, 0 possible duplicates e sai com código 0. Sua coluna RULE informa o padrão vencedor por linha, ou unmatched para a linha Unknown Shop. Revise as datas, beneficiários, valores de origem com sinal, contas de destino, correspondências duplicadas e a diferença proposta do arquivo. Corrija uma regra ou categoria incorreta, depois pré-visualize novamente. Abra qualquer conta ausente antes de aplicar a importação: uma regra que nomeia uma conta não aberta no livro-razão falha na validação.

3. Aplique as entradas revisadas​

bea --file books/main.bean import statement.csv --apply
bea --file books/main.bean check
bea --file books/main.bean list transaction --flag '!'
bea --file books/main.bean query "SELECT account, sum(position) WHERE account = 'Assets:Checking' GROUP BY account"

O mapeamento de colunas é lembrado por razão principal, linha de cabeçalho e conta de origem, então --apply é executado novamente sem flags e reporta usando o mapeamento de colunas lembrado. Ele recomputa a pré-visualização contra os arquivos atuais, valida o razão candidato completo antes de escrever e escreve 3 lançamentos. bea check não reporta erros. A fila ! lista a única linha sem correspondência: Unknown Shop com mystery em -9.99 USD. Uma verificação aprovada apenas prova que o razão está equilibrado e validado. Não diz nada sobre se essa linha pertence a Expenses:Uncategorized, então recategorize-a deliberadamente no seu razão. A verificação termina em 930.01 USD: o saldo inicial 1,000 USD menos 69.99 USD de gastos.

4. Importações repetidas não adicionam nada​

bea --file books/main.bean import statement.csv --apply

A pré-visualização reporta 0 ready, 3 exact duplicates, e a execução escreve 0 lançamentos com saída 0. Cada linha escrita carrega metadados import-id com um hash de conteúdo, então o arquivo idêntico corresponde a cada linha. Preserve esses metadados ao editar lançamentos importados. Importar adiciona lançamentos; não atualiza nem exclui uma transação existente. Faça correções deliberadamente no seu razão e execute bea check após isso. Entrada em massa JSON com bea add transactions não possui detecção de duplicados.

5. Resolver possíveis duplicatas​

Um download posterior pode repetir uma linha com narração ou IDs bancários diferentes. Data, beneficiário normalizado e valor da fonte assinado ainda a marcam como uma possível correspondência:

Status da pré-visualizaçãoSignificadoO que fazer
newNenhuma evidência de duplicata encontradaVerifique os valores e categorias
duplicateUm ID estável e detalhes da transação coincidem, ou existe uma diretiva não transacional idênticaJá pulado
possible_duplicateA data, beneficiário normalizado e valor/câmbio da fonte assinado coincidemCompare a pré-visualização com o lançamento existente
conflictUm ID estável coincide com detalhes de transação diferentesResolva a discrepância do ID ou dos dados, então pré-visualize novamente

Um ID bancário diferente não exclui uma duplicata. Bancos podem mudar IDs em downloads posteriores. Duas compras reais também podem compartilhar data, beneficiário e valor, logo uma possível correspondência é evidência e não prova. Bea não realiza suposições com modelo de IA e nunca categoriza para você além de suas regras.

O --duplicates review padrão recusa aplicar correspondências não resolvidas. Em uma execução de verificação, um segundo arquivo repetindo a linha 2026-08-02 Whole Foods -20.00 USD sob uma narração diferente foi exibido como 1 possível duplicata, e --apply saiu com 4 sem nada escrito. Depois de revisar todas as correspondências possíveis, escolha uma destas alternativas:

bea --file books/main.bean import statement.csv --apply --duplicates skip
bea --file books/main.bean import statement.csv --apply --duplicates include

Escolha include para preservar compras repetidas legítimas. A decisão se aplica a todas as correspondências possíveis nessa invocação. Duplicatas exatas continuam sendo ignoradas. Conflitos de ID ainda bloqueiam a gravação. --no-input e --yes não ignoram essa revisão. Uma decisão intencional de pular todas as linhas resulta em saída 0 sem adições ao livro razão.

6. Use um importador Python para outros formatos​

Para formatos que o mapeamento de colunas não pode expressar, como OFX ou QIF ou um CSV com layout incomum, bea import chama um importador configurado usando a interface atual do Beangulp: identify(filepath), account(filepath) e extract(filepath, existing). O importador é responsável pela análise e categorização específica do banco. Ele deve fornecer valores explícitos nos lançamentos da conta-fonte para que a correspondência de duplicatas use os valores reais do banco. Um importador Python continua sendo o caminho avançado para esses formatos. Para um CSV nativo de banco, experimente --csv primeiro.

Para uma primeira execução prática, salve a configuração CSV categorizada de exemplo como importers.py ao lado do seu livro razão raiz. Ele usa apenas Beancount e a biblioteca padrão do Python, então funciona com a instalação Homebrew. Seu exemplo bank.csv usa um valor assinado de conta corrente: uma despesa -5.25 USD para refeições e um depósito 1,000 USD de salário. A configuração de exemplo espera exatamente as colunas documentadas. Execute apenas configurações Python em que confie.

bea --file books/main.bean import bank.csv --config importers.py
bea --file books/main.bean import bank.csv --config importers.py --importer categorized-checking
bea --file books/main.bean import bank.csv --config importers.py --apply

Sua configuração importers.py exporta CONFIG = [importer, ...]. Se vários importadores reconhecerem o arquivo, selecione um pelo nome. Um nome desconhecido lista os nomes configurados. Um importador conhecido que não reconhece o arquivo reporta isso separadamente.

O CLI lembra o caminho da configuração para este livro razão raiz. Execuções futuras escolhem o --config explícito, depois o caminho lembrado e, por fim, importers.py ao lado do raiz. A saída indica o caminho e sua origem.

--apply recalcula a pré-visualização em relação aos arquivos atuais. Ele valida o razão candidato completo antes de escrever. Uma falha de validação deixa o razão original inalterado e sai com o código 1. Uma alteração simultânea no razão sai com o código 4; inspecione a alteração e execute uma nova pré-visualização antes de tentar novamente.

Mantenha as importações repetíveis​

Por padrão, a verificação de duplicatas compara os metadados bank_id, fitid, transaction_id e imported_id dentro da conta origem do importador. Use opções --id-key KEY repetidas para substituir esse conjunto.

Uma linha com um ID bancário estável é gravada com metadados import-id nomeando seu tipo, como um prefixo bank: ou ofx:. Uma linha sem esse ID é gravada com um hash de conteúdo csv:sha256: sobre sua data, valor, descrição e conta, portanto, reimportar o mesmo arquivo pula todas as linhas. Entradas gravadas antes desta convenção ainda podem conter metadados bea_import_id, e estes ainda correspondem na reimportação. Correspondências possíveis são verificadas contra transações existentes e linhas aceitas no mesmo lote.

Beneficiários, narrações e metadados de string substituem quebras de linha por espaços antes da pré-visualização e gravação. Aspas e barras invertidas mantêm seu conteúdo. O texto do comerciante importado permanece legível em uma única linha no razão.

Escrever em um arquivo incluído​

Mantenha --file apontado para a raiz e selecione o destino com --into:

bea --file books/main.bean import statement.csv --into 2026.bean
bea --file books/main.bean import statement.csv --into 2026.bean --apply

2026.bean deve já existir e estar incluído pela raiz. Seu caminho é relativo ao diretório raiz. O caminho de exportação permanece relativo ao seu diretório de trabalho. A pré-visualização identifica o arquivo que será alterado.

Use importações em um script​

bea --file books/main.bean --json --no-input import statement.csv --apply --duplicates skip

Escolha skip somente se essa for sua política intencional para possíveis correspondências. JSON retorna a pré-visualização e a contagem de gravação dentro de data. Aplicações recusadas colocam a pré-visualização em error.result no stderr, com written: 0. Sempre verifique o status de saída. Veja a referência de JSON e códigos de saída antes de agendar importações não supervisionadas.

Solucione problemas de um importador​

As configurações do importador rodam na engine gerenciada. Se uma configuração importa Beangulp, instale a biblioteca libmagic do sistema e habilite Beangulp lá uma vez:

bea engine enable beangulp
bea --file books/main.bean import bank.ofx --config importers.py
bea --debug --file books/main.bean import bank.csv --config importers.py

bea engine status reporta os recursos habilitados. Instalar um importador bancário junto à interface bea não o torna disponível dentro da engine. Uma configuração que importa pacotes adicionais precisa dessas dependências na engine; habilitar Beangulp sozinho não as instala. Use o mapeador CSV ou os conversores abaixo quando essas dependências do importador estiverem indisponíveis.

Para uma exceção de importador, coloque --debug antes do comando para mostrar seu rastreamento. A saída do importador é capturada em importer_output para que não corrompa o JSON. No modo de depuração JSON, o rastreamento é error.traceback.

Para uma conversão única sem um importador Python, experimente o conversor CSV ou o conversor OFX e QIF. Revise as entradas geradas antes de adicioná-las aos seus livros.

Fonte: https://beancount.io/pt/docs/Solutions/import-bank-exports-cli