Examples

Create some folder and related namespace files with your future queries. Like this, for example:

/queries
    users.sql

Prepare some SQL queries inside users.sql using block sql (Snaql is based on Jinja2 template engine and you can use it features):

{% sql 'users_by_country', note='counts users' %}
    SELECT count(*) AS count
    FROM user
    WHERE country_code = ?
{% endsql %}

Yes, that's it. Your SQL is inside sql block and note is an optional docstring for dynamically created function-generator with name 'users_by_country' in this case. You can use {% query %}{% endquery %} block if your query is too far from SQL. It's just an alias and this block equals to previous.

{% query 'users_by_country', note='counts users' %}
    SELECT count(*) AS count
    FROM user
    WHERE country_code = ?
{% endquery %}

What's next?

Import factory Snaql:

from snaql.factory import Snaql

Register SQL folder location:

root_location = os.path.abspath(os.path.dirname(__file__))
snaql_factory = Snaql(root_location, 'queries')

Register SQL template file with queries:

users_queries = snaql_factory.load_queries('users.sql')

Get rendered SQL by it's meta-name:

your_sql = users_queries.users_by_country()

# SELECT count(*) AS count
# FROM user
# WHERE country_code = ?

Cool! No?.. Hm, maybe you need some more flexibility? Remember, query blocks are Jinja-powered and you can render them with some context. Example:

# users.sql, you can add as many sql blocks in a single file as you need

{% sql 'users_select_cond', note='select users with condition' %}
    SELECT *
    FROM user
    {% if users_ids %}
        WHERE user_id IN ({{ users_ids|join(', ') }})
    {% endif %}
{% endsql %}

Get it without context:

your_sql = users_queries.users_select_cond()

# SELECT *
# FROM user

And with context:

sql_context = {'users_ids': [1, 2, 3]}
your_sql = users_queries.users_select_cond(**sql_context)

# SELECT *
# FROM user 
# WHERE user_id IN (1, 2, 3)

results matching ""

    No results matching ""