SQLite Export for YNAB - Export YNAB Data to SQLite
Project description
sqlite-export-for-ynab
SQLite Export for YNAB - Export YNAB Budget Data to SQLite
What This Does
Export all your YNAB plans to a local SQLite DB. Then you can query your data with any tools compatible with SQLite.
Installation
$ pip install sqlite-export-for-ynab
Usage
CLI
Provision a YNAB Personal Access Token and save it as an environment variable.
$ export YNAB_PERSONAL_ACCESS_TOKEN="..."
Run the tool from the terminal to download your plans:
$ sqlite-export-for-ynab
Running it again will pull only data that changed since the last pull (this is done with Delta Requests). If you want to wipe the DB and pull all data again use the --full-refresh flag.
You can specify the DB path with the following options
- The
--dbflag. - The
XDG_DATA_HOMEvariable (see the XDG Base Directory Specification). In that case the DB is saved in"${XDG_DATA_HOME}"/sqlite-export-for-ynab/db.sqlite. - If neither is set, the DB is saved in
~/.local/share/sqlite-export-for-ynab/db.sqlite.
Library
The library exposes the package sqlite_export_for_ynab and two functions - default_db_path and sync. You can use them as follows:
import asyncio
import os
from sqlite_export_for_ynab import default_db_path
from sqlite_export_for_ynab import sync
db = default_db_path()
token = os.environ["YNAB_PERSONAL_ACCESS_TOKEN"]
full_refresh = False
asyncio.run(sync(token, db, full_refresh))
Relations
The relations are defined in create-relations.sql. They are 1:1 with YNAB's OpenAPI Spec (ex: transactions, accounts, etc) with some additions:
- Some objects are pulled out into their own tables so they can be more cleanly modeled in SQLite (ex: subtransactions, loan account periodic values).
- Foreign keys are added as needed (ex: plan ID, transaction ID) so data across plans remains separate.
- Two new views called
flat_transactionsandscheduled_flat_transactions. These allow you to query split and non-split transactions easily, without needing to also querysubtransactionsandscheduled_subtransactionsrespectively. They also include fields to improve quality of life (ex:amount_majorto convert from YNAB's milliunits to major units i.e. dollars) and filter out deleted transactions/subtransactions.
Querying
You can issue queries with typical SQLite tools. sqlite-export-for-ynab deliberately does not implement a SQL REPL.
Sample Queries
To get the top 5 payees by spending per plan, you could do:
WITH
ranked_payees AS (
SELECT
pl."name" AS plan_name
, t.payee_name AS payee
, SUM(t.amount_major) AS net_spent
, ROW_NUMBER() OVER (
PARTITION BY
pl.id
ORDER BY
SUM(t.amount) ASC
) AS rnk
FROM
flat_transactions AS t
INNER JOIN plans AS pl
ON t.plan_id = pl.id
WHERE
t.payee_name != 'Starting Balance'
AND t.transfer_account_id IS NULL
GROUP BY
pl.id
, t.payee_id
)
SELECT
plan_name
, payee
, net_spent
FROM
ranked_payees
WHERE
rnk <= 5
ORDER BY
plan_name ASC
, net_spent DESC
;
To get duplicate payees, or payees with no transactions:
SELECT DISTINCT
pl."name" AS "plan"
, dupes."name" AS payee
FROM (
SELECT DISTINCT
p.plan_id
, p."name"
FROM payees AS p
LEFT JOIN flat_transactions AS ft
ON
p.plan_id = ft.plan_id
AND p.id = ft.payee_id
LEFT JOIN scheduled_flat_transactions AS sft
ON
p.plan_id = sft.plan_id
AND p.id = sft.payee_id
WHERE
TRUE
AND ft.payee_id IS NULL
AND sft.payee_id IS NULL
AND p.transfer_account_id IS NULL
AND p."name" != 'Reconciliation Balance Adjustment'
AND p."name" != 'Manual Balance Adjustment'
AND NOT p.deleted
UNION ALL
SELECT
plan_id
, "name"
FROM payees
WHERE NOT deleted
GROUP BY plan_id, "name"
HAVING COUNT(*) > 1
) AS dupes
INNER JOIN plans AS pl
ON dupes.plan_id = pl.id
ORDER BY "plan", payee
;
To count the spend for a category (ex: "Apps") between this month and the next 11 months (inclusive):
SELECT
plan_id
, SUM(amount_major) AS amount_major
FROM (
SELECT
plan_id
, amount_major
FROM flat_transactions
WHERE
category_name = 'Apps'
AND SUBSTR(`date`, 1, 7) = SUBSTR(DATE(), 1, 7)
UNION ALL
SELECT
plan_id
, amount_major * (
CASE
WHEN frequency = 'monthly' THEN 11
ELSE 1 -- assumes yearly
END
) AS amount_major
FROM scheduled_flat_transactions
WHERE
category_name = 'Apps'
AND SUBSTR(date_next, 1, 7) < SUBSTR(DATE('now', '+1 year'), 1, 7)
)
;
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sqlite_export_for_ynab-2.0.0.tar.gz.
File metadata
- Download URL: sqlite_export_for_ynab-2.0.0.tar.gz
- Upload date:
- Size: 16.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea22b3e49a8386e770d710df130250c120d1858da3c10d9ec61c31526ab21a88
|
|
| MD5 |
e13e908a5b646149732e522d4a2e03b2
|
|
| BLAKE2b-256 |
b232d8a306269fc548bd964f3ea0371d6566bcf435d0de81c03db3dc0820f0ba
|
File details
Details for the file sqlite_export_for_ynab-2.0.0-py2.py3-none-any.whl.
File metadata
- Download URL: sqlite_export_for_ynab-2.0.0-py2.py3-none-any.whl
- Upload date:
- Size: 16.4 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d3ba93d701f251d5e59da30d11a341617330158d0d0a764b9c5cb0f6b8804d4
|
|
| MD5 |
63e04802c59e452024961e3723ac0c00
|
|
| BLAKE2b-256 |
39c173d55782692a2c6c852e45caeb4f9344f513f1538fb0ba201122c9640070
|