Errors from run_query(), not from bean-query

26 views
Skip to first unread message

Eric Altendorf

unread,
Aug 2, 2023, 8:20:52 PM8/2/23
to bean...@googlegroups.com
I'm getting errors inside beancount/ops/summarize.py while using beanquery's run_query() programmatically.  This is on a beancount ledger that works fine when I run bean-query from the command line.  I'm not sure if I'm failing to use the programmatic API correctly or if there's something else going on.

bean-query access (works):

subprocess.run(["bean-query", ledger, query], check=True, capture_output=True) 

Programmatic access (doesn't work):

entries, errors, options = parser.parse_file(ledger)
run_query(entries, options, query)

The first error I got was this:
  ....
  File "/home/eric/crypto-taxes/beancount/beancount/ops/summarize.py", line 497, in conversions
    narration = 'Conversion for {}'.format(conversion_balance)
  File "/home/eric/crypto-taxes/beancount/beancount/core/inventory.py", line 122, in __str__
    return self.to_string()
  File "/home/eric/crypto-taxes/beancount/beancount/core/inventory.py", line 114, in to_string
    ', '.join(pos.to_string(dformat) for pos in sorted(self)))
  File "/home/eric/crypto-taxes/beancount/beancount/core/position.py", line 246, in __lt__
    return self.sortkey() < other.sortkey()
  File "/home/eric/crypto-taxes/beancount/beancount/core/position.py", line 227, in sortkey
    if self.cost.number:
AttributeError: 'CostSpec' object has no attribute 'number'

This was only a little surprising because I'm using the "{USD}" cost-spec hack, and I've had to elsewhere tweak beancount-core to be robust to such cost specs.  It's still a bit surprising since as I said don't get this error when running the bean-query tool on the same file.  Anyway, I hacked the comparator and got past this point, to:
  ....
  File "/home/eric/crypto-taxes/beancount/beancount/ops/summarize.py", line 480, in conversions
    conversion_balance = interpolate.compute_entries_balance(entries, date=date)
  File "/home/eric/crypto-taxes/beancount/beancount/core/interpolate.py", line 275, in compute_entries_balance
    total_balance.add_position(posting)
  File "/home/eric/crypto-taxes/beancount/beancount/core/inventory.py", line 461, in add_position
    return self.add_amount(position.units, position.cost)
  File "/home/eric/crypto-taxes/beancount/beancount/core/inventory.py", line 416, in add_amount
    key = (units.currency, cost)
AttributeError: type object 'MISSING' has no attribute 'currency'

So somehow I've got a missing value for some units.  I started tweaking this code too to be robust to this case, but there were too many places where it's assumed not-missing, and it seemed sketch to be hacking the code for adding to inventories this way.

Any idea what's going on?

Martin Blais

unread,
Aug 2, 2023, 8:54:40 PM8/2/23
to Beancount
Use bn.loader.load_file(), not just the parser.
Beancount has two stages: parsing, then booking and running all the plugins.
Loading does both.
The query is intended to be run on the output of the loader.

--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/CAFXPr0st_mX_NyovM%2BDkr8XJ%3D7Q048kOa8JHhUfCyaAcP9M0Zw%40mail.gmail.com.

Martin Blais

unread,
Aug 2, 2023, 8:55:37 PM8/2/23
to Martin Blais, Beancount
Btw, fwiw, the beanlabs repo has a bunch of random scripts you might find useful to eyeball, that use the api

Eric Altendorf

unread,
Aug 3, 2023, 1:20:45 AM8/3/23
to bean...@googlegroups.com, Martin Blais
On Wed, Aug 2, 2023 at 5:55 PM Martin Blais <bl...@furius.ca> wrote:

On Thu, Aug 3, 2023, 08:54 Martin Blais <bl...@furius.ca> wrote:
Use bn.loader.load_file(), not just the parser.
Beancount has two stages: parsing, then booking and running all the plugins.
Loading does both.
The query is intended to be run on the output of the loader.

Awesome.  I figured it must be something like that.
 
Btw, fwiw, the beanlabs repo has a bunch of random scripts you might find useful to eyeball, that use the api

Thanks, I had looked around for recipes but google was failing me.

Up and running.

 

Daniele Nicolodi

unread,
Aug 3, 2023, 5:04:11 AM8/3/23
to bean...@googlegroups.com
On 03/08/23 07:20, Eric Altendorf wrote:
>
> On Wed, Aug 2, 2023 at 5:55 PM Martin Blais <bl...@furius.ca
> <mailto:bl...@furius.ca>> wrote:
>
> On Thu, Aug 3, 2023, 08:54 Martin Blais <bl...@furius.ca
> <mailto:bl...@furius.ca>> wrote:
>
> Use bn.loader.load_file(), not just the parser.
> Beancount has two stages: parsing, then booking and running all
> the plugins.
> Loading does both.
> The query is intended to be run on the output of the loader.
>
> Awesome.  I figured it must be something like that.

BTW, I recently added another main entry point for the beanquery API
that should make its use a bit easier:

import beanquery
connection = beanquery.connect('beancount:' + filename)
types, rows = connection.execute('''SELECT ...''')

It is a first step into providing a Python DB-API interface, thus it
will be further transformed, but if you want to experiment with it, it
works in the form above now.

Cheers,
Dan

Reply all
Reply to author
Forward
0 new messages