Hacker News new | ask | show | jobs
by ksri 3321 days ago
Jinjasql is meant for reporting use cases, so yes - it should be able to help you. However, when we made JinjaSQL, we didn't want to build a super-expressive reporting API. Instead, for every report/chart we wanted to make, we wrote a comparatively simpler query and used jinjasql to get it working.

If you have a single complex query that is generating all your reports based on database configuration - I'm guessing you need the full power of python. So while JinjaSQL could have save some effort, I'm not sure it'd save you a lot.

Hope that helps!

1 comments

Thanks!

The reports are all API driven. User specifies dimensions and metrics, as well as filters, etc. The API returns the JSON response.

I can't predict what users will want to visualize in the future, so dedicated templates for each of the visualizations are not practical for my use case.

The goal is to minimize dev work on the API and let front end config dictate what columns the API returns.

Let's assume you have a python object "userquery" that has the user specifications - including dimensions, metrics, filters and the cube to query. I'm also assuming you have whitelisted all the parameters in this object per your database model, otherwise you are open to security issues.

Here's how you could write that in jinjasql. I'm writing this out of memory, and it has errors/issues - but I hope you get the idea.

    SELECT
    {% for metric in userquery.metrics %}
        {{ metric.id }} as '{{metric.description}}'
    {% endfor %}
    FROM {{ userquery.cube }}
    WHERE 
    {% for filter in userquery.filters %}
        {{ filter.key }} {{ filter.operator }} {{ filter.value }}
    {% endfor %}
    GROUP BY 
    {% for dimension in userquery.dimensions %}
        {{ dimension }}
    {% endfor %}
This way, your template doesn't have to map to exactly one visualization.

Now, another interesting this in the security aspect. You can also pass the logged in user data model, and then append a where clause that restricts the rows based on the logged in user id or his role or whatever else is your application security model.

I'm not sure how much effort it would have saved you, but it does help us a lot - mostly because we don't have to translate between SQL and the way SQL ALchemy / ORM works.

Thanks for the example, this helps a lot in my understanding of this!

It's pretty similar to what I did, but the template would be a lot more complex due to various column definitions and calculations, for example uniques require the base query to have the IDs of whatever I'm counting, but all in all I see the use case.

Is that safe from sqli prospective? It would inject table name and all, which I believe you can't bind...
You're right. That's why I said upfront - whitelist values in the userquery object.