Lightweight wrapper around sqlalchemy + jinja2.
pip install jsql==0.9
Check tests for examples.
from jsql import sql
engine = sqlalchemy.create_engine('...')
with engine.begin() as conn:
ctx = {'lang': 'en', 'country': 'us'}
ids = [1, 2, 3, 4, 5]
limit = 100
products = sql(conn, '''
SELECT id, title_{{lang}} as title
FROM product_{{country}}
WHERE 1=1
{% if price_min %}AND price > :price_min{% endif %}
{% if id_list %}AND id IN :id_list{% endif %}
LIMIT {{limit}}
{% endif %}
''', limit=limit, id_list=ids, **ctx).dicts()
- Return value is a wrapper around sqlalchemy resultproxy with some helper methods (see
jsql.SqlProxy
andtest_sqlproxy
) - First parameter can be a sqlalchemy engine, connection, or session
- Variables injected using
:var
will be escaped by SQL driver. - Variables injected as
:var_list
will expect a list value and will be escaped by SQL driver for use as egid IN :id_list
(seetest_list_param
) - Variables injected as
:var_tuple_list
will expect a list of tuples and will be escaped by SQL driver for use as eg(id1, id2) IN :id_tuple_list
(seetest_list_param
) - Variables injected using
{{var}}
will be inserted directly into the query but will be checked against jsql.NOT_DANGEROUS_RE (default[A-Za-z0-9_]+
). This is intended for templating table names, limits, etc where SQL query placeholders are not allowed. (seetest_render
) - Variables injected using
{{var | dangerously_inject_sql }}
will be inserted directly into the query without any checks (probably a bad idea) (seetest_render
)