0

Let's say I have the following str:

sql = "SELECT c1, c2 FROM {{ table1 }} LEFT JOIN {{ table2 }}"

And I want to render it without specifying the values of table1 and table2, and they should have a default value specified by me i.e "table". So the rendered str would be:

rendered_sql = "SELECT c1, c2 FROM table LEFT JOIN table"

I need to render hundreds of similar strings, and each of them could have an arbitrary number of variables, with no shared names between them, so I can't do things like {{ table1 or 'table' }} or {{ table1|default('foo') }} because it would involve a lot of manual work for modifying all the strings. The value can't be a blank string either.

In conclusion, I would want for the following strings:

str_1 = "SELECT c1, c2 FROM {{ table1 }} LEFT JOIN {{ table2 }}"
str_2 = "SELECT c3, c4 FROM {{ table4 }} LEFT JOIN {{ table7 }} INNER JOIN {{ prior_table0 }}"

To be rendered like:

"SELECT c1, c2 FROM default_value LEFT JOIN default_value"
"SELECT c3, c4 FROM default_value LEFT JOIN default_value INNER JOIN default_value"

Because none of the variables is defined, and I dont want to manually add the default value for each of the variables

Is this possible? Thanks

Javier Lopez Tomas
  • 2,072
  • 3
  • 19
  • 41
  • Does this answer your question? [Jinja2 template variable if None Object set a default value](https://stackoverflow.com/questions/19614027/jinja2-template-variable-if-none-object-set-a-default-value) – Epsi95 Oct 31 '22 at 11:51

1 Answers1

1

It sounds at first like you're looking for the default filter:

sql = "SELECT c1, c2 FROM {{ table1|default('foo') }} LEFT JOIN {{ table2|default('bar') }}"

...but I'm unclear about that last sentence in your question, "The numbers of variables that are going to be not defined is arbitrary, as well as the names of them...". If the default filter doesn't solve your problem, it would be great if you could update your question with some clear examples of the behavior you're looking for.


If you want all the undefined values to have the same default value, and if you have some control over the content of the templates, you could use a defaultdict.

If you define your SQL templates like this:

str_1 = "SELECT c1, c2 FROM {{ context.table1 }} LEFT JOIN {{ context.table2 }}"
str_2 = "SELECT c3, c4 FROM {{ context.table4 }} LEFT JOIN {{ context.table7 }} INNER JOIN {{ context.prior_table0 }}"

Then you can do something like this:

>>> import jinja2
>>> from collections import defaultdict
>>> context = defaultdict(lambda: "default_value")
>>> print(jinja2.Template(str_1).render(context=context))
SELECT c1, c2 FROM default_value LEFT JOIN default_value
>>> print(jinja2.Template(str_2).render(context=context))
SELECT c3, c4 FROM default_value LEFT JOIN default_value INNER JOIN default_value
larsks
  • 277,717
  • 41
  • 399
  • 399