Saltar al contenido principal

Importa un CSV bancario a Beancount con bea

Importa un CSV bancario a tu libro mayor de Beancount con bea: asigna columnas, categoriza con reglas, previsualiza asientos, revisa duplicados y luego aplícalos.

Un CSV bancario ordinario no necesita un importador en Python. Mapea sus columnas con --csv, nombra la cuenta origen con --account, categoriza las filas con --rules, y luego previsualiza y aplica las entradas con bea import.

Necesitas un libro contable existente. Si estás empezando libros nuevos, sigue la guía rápida de CLI. Conserva la exportación bancaria original para poder compararla con la previsualización.

1. Mapea las columnas del CSV​

Guarda este ejemplo como statement.csv, luego ejecuta los comandos abajo desde el mismo directorio:

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

Los montos usan la convención de signo bancario: el gasto es negativo y el depósito positivo. La moneda por defecto es la moneda operativa del libro, así que este archivo no necesita columna de moneda. Pon una columna de descripción bancaria en narration y conserva payee para el comercio.

Crea el libro y abre la subcuenta de combustible usada abajo:

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

La plantilla ya abre Expenses:Groceries y las otras cuentas comunes. No abre Expenses:Transport:Fuel, así que el segundo comando la abre antes de la importación. Opciones globales como --file van antes del subcomando.

2. Previsualiza las entradas​

Guarda estas reglas de categorización como rules.toml, luego previsualiza:

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

Las reglas coinciden primero con el beneficiario, luego con la narración, ignorando mayúsculas. La primera regla que coincide gana. Las filas que no cumplen ninguna regla se registran en Expenses:Uncategorized con la bandera ! para revisión posterior. La guía IMPORTING del producto documenta la referencia completa del mapeo, incluyendo el par debit y credit, la columna category, y la lectura de encabezados --csv auto.

Nada se escribe aún en el libro. La previsualización reporta 3 ready, 0 exact duplicates, 0 possible duplicates y sale con código 0. Su columna RULE nombra el patrón ganador por fila, o unmatched para la fila Unknown Shop. Revisa las fechas, beneficiarios, montos con signo, cuentas destino, coincidencias duplicadas y la propuesta de diferencia de archivo. Corrige una regla o categoría incorrecta y previsualiza de nuevo. Abre las cuentas faltantes antes de aplicar la importación: una regla que nombra una cuenta que el libro no abre falla la validación.

3. Aplica las 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"

La asignación de columnas se recuerda por libro mayor, fila de encabezado y cuenta de origen, por lo que --apply se vuelve a ejecutar sin banderas y reporta usando la asignación de columnas recordada. Recomputa la vista previa contra los archivos actuales, valida el libro mayor candidato completo antes de escribir, y escribe 3 entradas. bea check no reporta errores. La cola ! lista la única fila no coincidente: Unknown Shop con mystery en -9.99 USD. Una verificación exitosa solo prueba que el libro mayor está balanceado y validado. No dice nada sobre si esa fila pertenece a Expenses:Uncategorized, así que recategorízala deliberadamente en tu libro mayor. La verificación termina en 930.01 USD: el saldo inicial 1,000 USD menos 69.99 USD de gastos.

4. Las importaciones repetidas no añaden nada​

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

La vista previa reporta 0 ready, 3 exact duplicates, y la ejecución escribe 0 entradas con salida 0. Cada fila escrita lleva metadatos import-id con un hash de contenido, por lo que el archivo idéntico coincide con cada fila. Conserva esos metadatos al editar las entradas importadas. Importar añade entradas; no actualiza ni elimina una transacción existente. Realiza correcciones deliberadas en tu libro mayor y ejecuta bea check después. La entrada masiva JSON con bea add transactions no detecta duplicados.

5. Resolver posibles duplicados​

Una descarga posterior puede repetir una fila con narración o IDs bancarios diferentes. La fecha, el beneficiario normalizado y el monto fuente firmado aún lo marcan como una posible coincidencia:

Estado de vista previaSignificadoQué hacer
newNo se encontró evidencia de duplicadosVerificar los montos y categorías
duplicateCoincidencia de ID estable y detalles de transacción, o existe una directiva no transaccional idénticaYa omitido
possible_duplicateLa fecha, beneficiario normalizado y monto/divisa fuente firmada coincidenComparar la vista previa con la entrada existente
conflictUn ID estable coincide con diferentes detalles de transacciónResolver la discrepancia del ID o datos, luego previsualizar de nuevo

Un ID bancario diferente no descarta un duplicado. Los bancos pueden cambiar IDs en descargas posteriores. Dos compras reales también pueden compartir fecha, beneficiario y monto, por lo que una posible coincidencia es evidencia y no prueba. Bea no adivina con un modelo AI ni clasifica por ti más allá de tus reglas.

El --duplicates review predeterminado se niega a aplicar coincidencias no resueltas. En una ejecución de verificación, un segundo archivo que repite la fila 2026-08-02 Whole Foods -20.00 USD bajo una narración diferente se previsualizó como 1 posible duplicado, y --apply salió con código 4 sin escribir nada. Después de revisar cada posible coincidencia, elija una de estas alternativas:

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

Elija include para preservar las compras legítimamente repetidas. La decisión se aplica a todas las coincidencias posibles en esa invocación. Los duplicados exactos siguen siendo omitidos. Los conflictos de ID aún bloquean la escritura. --no-input y --yes no evitan esa revisión. Una decisión intencional de omitir todas las filas sale con código 0 sin añadir nada al libro mayor.

6. Use un importador Python para otros formatos​

Para formatos que el mapeo de columnas no puede expresar, como OFX o QIF o un CSV con un diseño inusual, bea import llama a un importador configurado usando la interfaz actual de Beangulp: identify(filepath), account(filepath) y extract(filepath, existing). El importador se encarga del análisis y la categorización específica del banco. Debe suministrar montos explícitos en las anotaciones de la cuenta de origen para que la coincidencia de duplicados use los montos reales del banco. Un importador Python sigue siendo el camino avanzado para estos formatos. Para un CSV nativo de un banco, pruebe primero con --csv.

Para una primera ejecución práctica, guarde la configuración de ejemplo CSV categorizada como importers.py junto a su libro mayor raíz. Usa solo Beancount y la biblioteca estándar de Python, así que funciona con la instalación de Homebrew. Su muestra bank.csv utiliza un monto firmado de una cuenta corriente: un gasto -5.25 USD en comidas y un depósito 1,000 USD de salario. La configuración de ejemplo espera exactamente sus columnas documentadas. Ejecute solo configuraciones Python en las que confíe.

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

Su configuración importers.py exporta CONFIG = [importer, ...]. Si varios importadores reconocen el archivo, seleccione uno por nombre. Un nombre desconocido lista los nombres configurados. Un importador conocido que no reconoce el archivo informa eso por separado.

La CLI recuerda la ruta de configuración para este libro mayor raíz. Ejecuciones futuras eligen primero el --config explícito, luego la ruta recordada y luego importers.py junto al raíz. La salida nombra la ruta y su origen.

--apply recalcula la vista previa contra los archivos actuales. Valida el libro contable candidato completo antes de escribir. Un fallo de validación deja el libro contable original sin cambios y sale con código 1. Un cambio concurrente en el libro contable sale con código 4; inspeccione el cambio y ejecute una vista previa nueva antes de reintentar.

Mantenga las importaciones repetibles​

Por defecto, la verificación de duplicados coincide con los metadatos bank_id, fitid, transaction_id y imported_id dentro de la cuenta origen del importador. Use opciones --id-key KEY repetidas para reemplazar ese conjunto.

Una fila con un ID bancario estable se escribe con metadatos import-id que nombran su tipo, como un prefijo bank: o ofx:. Una fila sin uno se escribe con un hash de contenido csv:sha256: sobre su fecha, monto, descripción y cuenta, por lo que reimportar el mismo archivo omite cada fila. Las entradas escritas antes de esta convención pueden aún llevar metadatos bea_import_id, y esos aún coinciden en la reimportación. Las coincidencias posibles se verifican contra transacciones existentes y filas aceptadas en el mismo lote.

Los beneficiarios, narraciones y metadatos de cadena reemplazan los saltos de línea por espacios antes de la vista previa y escritura. Las comillas y barras invertidas conservan su contenido. El texto de comerciantes importado por lo tanto permanece legible en una sola línea del libro contable.

Escribir en un archivo incluido​

Mantenga --file apuntando a la raíz y seleccione el destino con --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 debe existir ya y estar incluido por la raíz. Su ruta es relativa al directorio raíz. La ruta de exportación permanece relativa a su directorio de trabajo. La vista previa identifica el archivo que cambiará.

Usar importaciones en un script​

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

Elija skip solo cuando esa sea su política prevista para posibles coincidencias. JSON devuelve la vista previa y la cuenta de escritura dentro de data. Las aplicaciones rechazadas ponen la vista previa en error.result en stderr, con written: 0. Siempre verifique el estado de salida. Consulte la referencia JSON y códigos de salida antes de programar importaciones desatendidas.

Solucionar problemas de un importador​

Las configuraciones del importador se ejecutan en el motor gestionado. Si una configuración importa Beangulp, instale la biblioteca del sistema libmagic y habilite Beangulp allí una 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 informa las funciones habilitadas. Instalar un importador bancario junto al frontend bea no lo hace disponible dentro del motor. Una configuración que importa paquetes adicionales necesita esas dependencias en el motor; habilitar solo Beangulp no las instala. Use el mapeador CSV o los convertidores abajo cuando esas dependencias del importador no estén disponibles.

Para una excepción de importador, coloque --debug antes del comando para mostrar su traceback. La salida del importador se captura en importer_output para que no corrompa el JSON. En modo de depuración JSON, el traceback es error.traceback.

Para una conversión única sin un importador de Python, pruebe el convertidor CSV o el convertidor OFX y QIF. Revise las entradas generadas antes de agregarlas a sus libros.

Fuente: https://beancount.io/es/docs/Solutions/import-bank-exports-cli