Перейти к основному содержимому

Импорт банковского CSV в Beancount с помощью bea

Импортируйте банковский CSV в свой журнал Beancount с помощью bea: сопоставьте столбцы, распределите по категориям с помощью правил, просмотрите проводки, проверьте дубликаты и примените их.

Обычный банковский CSV не требует Python импортёра. Отобразите его столбцы с помощью --csv, укажите исходный счёт с --account, категоризируйте строки через --rules, затем просмотрите и примените записи с bea import.

Вам нужна существующая бухгалтерская книга. Если вы начинаете с нуля, следуйте быстрому старту CLI. Сохраните оригинальный банковский экспорт для сравнения с превью.

1. Отобразите столбцы CSV​

Сохраните этот пример как statement.csv, затем выполните команды ниже из той же директории:

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

Суммы используют банковскую конвенцию знаков: расход — отрицателен, депозит — положителен. Валюта по умолчанию — операционная валюта книги, поэтому столбец валюты не требуется. В столбце narration разместите описание банка, а payee оставьте для торговца.

Создайте бухгалтерскую книгу и откройте используемый ниже субсчет топлива:

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

Шаблон уже открывает Expenses:Groceries и другие общие счета. Он не открывает Expenses:Transport:Fuel, поэтому вторая команда открывает его перед импортом. Глобальные опции, такие как --file, указываются перед подкомандой.

2. Просмотр записей​

Сохраните эти правила категоризации как rules.toml, затем выполните просмотр:

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

Правила сначала соответствуют получателю платежа, затем описанию, игнорируя регистр. Первое совпадение применяется. Строки без подходящего правила отправляются в Expenses:Uncategorized с флагом ! для последующего рассмотрения. В руководстве по ИМПОРТИРОВАНИЮ описаны полные справочные сведения по отображению, включая пару debit и credit, столбец category и чтение заголовков --csv auto.

Пока что в книгу ничего не записывается. Превью выводит 3 ready, 0 exact duplicates, 0 possible duplicates и завершает работу с кодом 0. Его столбец RULE указывает выигравший шаблон для каждой строки или unmatched для строки Unknown Shop. Проверьте даты, получателей, подписанные суммы источника, счета назначения, дубликаты и предполагаемые изменения файла. Исправьте ошибочное правило или категорию, затем повторите просмотр. Откройте все отсутствующие счета перед применением импорта: правило, указывающее счет, который не открыт в книге, не проходит проверку.

3. Примените проверенные записи​

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"

Сопоставление столбцов запоминается для каждой книги, строки заголовка и исходного счета, поэтому --apply запускается повторно без флагов и отчитывается, используя запомненное сопоставление столбцов. Он пересчитывает предварительный просмотр по текущим файлам, проверяет полную кандидатуру книги перед записью и записывает 3 записи. bea check сообщает об отсутствии ошибок. Очередь ! содержит одну несопоставленную строку: Unknown Shop с mystery в -9.99 USD. Прохождение проверки лишь доказывает, что книга сбалансирована и валидна. Это ничего не говорит о том, принадлежит ли эта строка Expenses:Uncategorized, поэтому переклассифицируйте её осознанно в вашей книге. Проверка заканчивается на 930.01 USD: начальный баланс 1,000 USD минус расходы 69.99 USD.

4. Повторный импорт ничего не добавляет​

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

Предварительный просмотр сообщает 0 ready, 3 exact duplicates, а запуск записывает 0 записей с кодом выхода 0. Каждая записанная строка содержит метаданные import-id с хэшом содержимого, поэтому идентичный файл совпадает с каждой строкой. Сохраняйте эти метаданные при редактировании импортированных записей. Импорт добавляет записи; он не обновляет и не удаляет существующую транзакцию. Вносите исправления осознанно в своей книге и запускайте bea check после этого. Массовый ввод JSON с bea add transactions не обнаруживает дубликатов.

5. Разрешение возможных дубликатов​

Поздняя загрузка может повторить строку с другим описанием или банковскими идентификаторами. Дата, нормализованный плательщик и подписанная исходная сумма по-прежнему указывают на возможное совпадение:

Статус предварительного просмотраЗначениеЧто делать
newДоказательств дубликата не найденоПроверьте суммы и категории
duplicateСовпадение стабильного идентификатора и деталей транзакции, или существует идентичная директива без транзакцииУже пропущено
possible_duplicateСовпадение даты, нормализованного плательщика и подписанной суммы/валютыСравните предварительный просмотр с существующей записью
conflictСовпадение стабильного идентификатора с отличающимися деталями транзакцииРешите расхождение в идентификаторе или данных, затем повторите предварительный просмотр

Различный банковский идентификатор не исключает дубликат. Банки могут менять идентификаторы при последующих загрузках. Две реальные покупки также могут иметь одинаковую дату, плательщика и сумму, поэтому возможное совпадение — это доказательство, а не подтверждение. Bea не делает предположений с помощью ИИ-модели и никогда не присваивает категории за вас, кроме тех, что заданы вашими правилами.

По умолчанию --duplicates review отказывается применять неразрешённые совпадения. В проверочном запуске второй файл с повторяющейся строкой 2026-08-02 Whole Foods -20.00 USD под другим описанием был предварительно показан как 1 возможный дубликат, а --apply завершился с кодом 4 без записи данных. После рассмотрения всех возможных совпадений выберите один из следующих вариантов:

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

Выберите include, чтобы сохранить законные повторяющиеся покупки. Это решение применяется ко всем возможным совпадениям в данном вызове. Точные дубликаты продолжают пропускаться. Конфликты ID по-прежнему блокируют запись. --no-input и --yes не обходят эту проверку. Сознательное решение пропустить каждую строку приводит к завершению с кодом 0 без изменений в книге учета.

6. Используйте Python-импортер для других форматов​

Для форматов, которые нельзя выразить сопоставлением столбцов, таких как OFX или QIF или CSV с необычной структурой, bea import вызывает настроенный импортер, используя текущий интерфейс Beangulp: identify(filepath), account(filepath) и extract(filepath, existing). Импортер отвечает за парсинг и категоризацию, специфичные для банка. Он должен обеспечивать явные суммы по проводкам с исходного счёта, чтобы совпадения дубликатов использовали фактические банковские суммы. Python-импортер остаётся продвинутым способом работы с этими форматами. Для родного CSV банка сначала попробуйте --csv.

Для первого пробного запуска сохраните пример конфигурации категоризированного CSV как importers.py рядом с вашим корневым файлом книги учета. Он использует только Beancount и стандартную библиотеку Python, поэтому работает с установкой Homebrew. Его пример bank.csv использует подписанную сумму по текущему счёту: -5.25 USD в ресторан и 1,000 USD зарплатный депозит. Пример конфигурации ожидает ровно указанные в документации столбцы. Выполняйте только те Python-конфигурации, которым доверяете.

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

Ваша конфигурация importers.py экспортирует CONFIG = [importer, ...]. Если несколько импортеров распознают файл, выберите один по имени. Неизвестное имя выведет список настроенных имён. Известный импортер, который не распознаёт файл, сообщит об этом отдельно.

CLI запоминает путь конфигурации для этого корневого файла книги учета. Последующие запуски выбирают явно указанный --config, затем запомненный путь, затем importers.py рядом с корнем. В выводе указывается путь и его источник.

--apply пересчитывает предварительный просмотр на основе текущих файлов. Он выполняет проверку полного кандидата учета перед записью. При ошибке проверки исходный учет остается без изменений, и программа завершается с кодом 1. При одновременном изменении учета программа завершается с кодом 4; проверьте изменения и выполните новый предварительный просмотр перед повторной попыткой.

Делайте импорт повторяемым​

По умолчанию, дублированное совпадение проверяет метаданные bank_id, fitid, transaction_id и imported_id в исходном счете импортера. Используйте повторяющиеся параметры --id-key KEY, чтобы заменить этот набор.

Строка с устойчивым банковским идентификатором записывается с метаданными import-id, указывающими его тип, например, с префиксом bank: или ofx:. Строка без такого идентификатора записывается с хэшом содержимого csv:sha256:, основанным на дате, сумме, описании и счете, так что повторный импорт того же файла пропускает каждую строку. Записи, сделанные до этого соглашения, могут содержать метаданные bea_import_id и при повторном импорте по-прежнему совпадают. Возможные совпадения проверяются по существующим транзакциям и принятым строкам в той же партии.

Получатели, описания и строковые метаданные перед предварительным просмотром и записью заменяют переносы строк пробелами. Кавычки и обратные слэши сохраняют своё содержимое. Текст импортированных торговцев таким образом остаётся читаемым в одной строке учета.

Запись во включенный файл​

Оставьте --file, указывающий на корень, и выберите место назначения с помощью --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 должен уже существовать и быть включён в корневой файл. Его путь относителен корневого каталога. Путь экспорта остаётся относительным текущей рабочей директории. Предпросмотр показывает, какой файл будет изменён.

Использование импортов в скрипте​

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

Выбирайте skip только если это ваша ожидаемая политика для возможных совпадений. JSON возвращает предварительный просмотр и количество записей внутри data. Отклонённые запросы помещают предварительный просмотр в error.result на stderr с written: 0. Всегда проверяйте код выхода. См. Справочник по JSON и коду выхода перед планированием неуправляемых импортов.

Поиск и устранение неполадок импортера​

Конфигурации импортера выполняются в управляемом движке. Если конфигурация импортирует Beangulp, установите системную библиотеку libmagic и включите Beangulp там один раз:

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 сообщает о включённых функциях. Установка банковского импортера вместе с фронтендом bea не делает его доступным внутри движка. Конфигурация, которая импортирует дополнительные пакеты, требует этих зависимостей в движке; включение Beangulp само по себе не устанавливает их. Используйте CSV-мэппер или конвертеры ниже, если зависимости импортера недоступны.

Для исключения импортера поместите --debug перед командой, чтобы показать её трассировку. Вывод импортера захватывается в importer_output, чтобы не портить JSON. В режиме отладки JSON трассировка — error.traceback.

Для одноразового преобразования без Python импортера попробуйте конвертер CSV или конвертер OFX и QIF. Проверьте созданные записи перед добавлением их в свои книги.

Источник: https://beancount.io/ru/docs/Solutions/import-bank-exports-cli