Scripting Bean-query

318 views
Skip to first unread message

ande...@gmail.com

unread,
Sep 27, 2016, 9:18:04 AM9/27/16
to Beancount
Hello all.  To create my monthly cash-flow report, I need run multiple sql (bql?) queries (one for income, tithing, savings, etc).

I would like to create a python script to automate this process.  But every time I:
'
proc = subprocess.Popen('bean-query 2016-09.bc',
                        shell=True,
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        )
'

The input becomes speratic, slow and just strange.  Usually coming back with an error (after Ctrl-C)
'
Traceback (most recent call last):
  File "/usr/local/bin/bean-query", line 2, in <module>
    from beancount.query.shell import main; main()
  File "/usr/local/lib/python3.5/dist-packages/beancount/query/shell.py", line 716, in main
    shell_obj.cmdloop()
  File "/usr/local/lib/python3.5/dist-packages/beancount/query/shell.py", line 158, in cmdloop
    super().cmdloop()
  File "/usr/lib/python3.5/cmd.py", line 126, in cmdloop
    line = input(self.prompt)
OSError: [Errno 5] Input/output error
'
and Regretfully /usr/lib/python3.5/cmd.py is standard python code.  Maybe give it another option for playing nice this way?

Is there an easier way to script bean-query (without opening and closing bean-query for every query)?  

I guess I could "bean-query 2016-09 'quer1' 'query2' 'query3'" (stack all of my queries) and then just parse the output...

Any other ideas?

Matthew 7:7
  Craig A.

ande...@gmail.com

unread,
Sep 27, 2016, 10:42:34 AM9/27/16
to Beancount, ande...@gmail.com
Maybe a 
bean-query [-i INPUT]
option?

Martin Blais

unread,
Sep 28, 2016, 11:12:31 AM9/28/16
to Beancount
On Tue, Sep 27, 2016 at 9:18 AM, <ande...@gmail.com> wrote:
Hello all.  To create my monthly cash-flow report, I need run multiple sql (bql?) queries (one for income, tithing, savings, etc).

I would like to create a python script to automate this process.  But every time I:
'
proc = subprocess.Popen('bean-query 2016-09.bc',
                        shell=True,
                        stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        )

The input becomes speratic, slow and just strange.  Usually coming back with an error (after Ctrl-C)
'
Traceback (most recent call last):
  File "/usr/local/bin/bean-query", line 2, in <module>
    from beancount.query.shell import main; main()
  File "/usr/local/lib/python3.5/dist-packages/beancount/query/shell.py", line 716, in main
    shell_obj.cmdloop()
  File "/usr/local/lib/python3.5/dist-packages/beancount/query/shell.py", line 158, in cmdloop
    super().cmdloop()
  File "/usr/lib/python3.5/cmd.py", line 126, in cmdloop
    line = input(self.prompt)
OSError: [Errno 5] Input/output error
'
and Regretfully /usr/lib/python3.5/cmd.py is standard python code.  Maybe give it another option for playing nice this way?

This is normal. You're running the script in interactive mode. It's probably waiting for input.
The typical way people deal with those types of interactive things is to use a library called "expect."
It's a little tricky.

But you shouldn't have to do this; there's a better way.

 

Is there an easier way to script bean-query (without opening and closing bean-query for every query)?  

In order to run in batch mode, just provide the query you'd like to run as a third argument, it should just output the results.

  bean-query <filename> <query>

should just work.

Moreover, you should always avoid using shell=True if you can. Use shell=False, and provide a list of the three arguments. This way you avoid all the complications around having a shell break out the arguments using whitespace rules.

Finally, instead of running a subprocess, why don't you just call library functions directly?
All of Beancount is written in Python, if you're on Python3, there's no reason you couldn't just load the file to its entries and run the queries on that. See here for the entry point:

Look at places where this is called in the source code in order to see how to use it.
You'd have to (1) call loader.load_file(), (2) pass on the args to run_query(), and (3) call one of the rendering routines.

If it would help to have a Python function that automatically does all this I can provide.

That's the best way to do this,




I guess I could "bean-query 2016-09 'quer1' 'query2' 'query3'" (stack all of my queries) and then just parse the output...

Any other ideas?

Matthew 7:7
  Craig A.

--
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+unsubscribe@googlegroups.com.
To post to this group, send email to bean...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/8c9d192e-725a-4d8e-a1c1-0a73e61d5b53%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages