Coming from the Ledger half of the Free accounting world, I'm used to the fact that transaction metadata propagates down to postings. Please correct me if I'm wrong, but this doesn't seem to be the case in Beancount, at least according to my experiments with bean-query.
I'm fine with Beancount model for this. But when querying it is sometimes handy to have a way to lookup a metadata *first* in a posting, and then fallback to the parent transaction if the metadata key is not defined in the posting. Is there a way to implement this in Beancount SQL language? E.g., is there a boolean (or n-ary) operator that takes two (or more) values and return the first of them that is not NULL? Either way, it might be helpful to have a SQL function that will lookup a metadata key first in a posting and then fallbacks on the parent transaction. Attached you can find a proposal for such a function, called ANY_META for lack of better naming ideas. It works for me, but I'm open to better suggestion on how to "hierarchically" lookup metadata within transactions. Cheers. -- Stefano Zacchiroli . [email protected] . upsilon.cc/zack . . o . . . o . o Computer Science Professor . CTO Software Heritage . . . . . o . . . o o Former Debian Project Leader . OSI Board Director . . . o o o . . . o . « the first rule of tautology club is the first rule of tautology club » -- 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 [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/20161114143819.ry4mhqp2ermizo3c%40upsilon.cc. For more options, visit https://groups.google.com/d/optout.
>From aa65ae27a2472d4a3c1ec9c0eaea9a25a3e91dc2 Mon Sep 17 00:00:00 2001 From: Stefano Zacchiroli <[email protected]> Date: Mon, 14 Nov 2016 15:29:58 +0100 Subject: [PATCH] add new ANY_META() SQL function to query posting OR entry metadata the function will first lookup the given metadata key in the current posting, falling back to the parent transaction if and only if the key is not defined for the posting --- src/python/beancount/query/query_env.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/python/beancount/query/query_env.py b/src/python/beancount/query/query_env.py index 850422c..a345665 100644 --- a/src/python/beancount/query/query_env.py +++ b/src/python/beancount/query/query_env.py @@ -244,6 +244,29 @@ class EntryMeta(query_compile.EvalFunction): return None return meta.get(args[0], None) +class AnyMeta(query_compile.EvalFunction): + "Get metadata key of the Posting, falling back to parent Transaction" + __intypes__ = [str] + + def __init__(self, operands): + super().__init__(operands, object) + + def __call__(self, context): + args = self.eval_args(context) + + meta_key = args[0] + entry_meta = context.entry.meta + posting_meta = context.posting.meta + + # note: if the looked up key is explicitly defined in posting as None, + # we return it as such, rather than falling back to parent Transaction + if posting_meta and meta_key in posting_meta: + return posting_meta.get(meta_key, None) + elif entry_meta and meta_key in entry_meta: + return entry_meta.get(meta_key, None) + else: + return None + class OpenMeta(query_compile.EvalFunction): "Get the metadata dict of the open directive of the account." __intypes__ = [str] @@ -629,6 +652,7 @@ SIMPLE_FUNCTIONS = { 'close_date' : CloseDate, 'meta' : Meta, 'entry_meta' : EntryMeta, + 'any_meta' : AnyMeta, 'open_meta' : OpenMeta, 'commodity_meta' : CommodityMeta, 'account_sortkey' : AccountSortKey, -- 2.10.2
