如何将所有模板放在一个文件中并从 python 代码在 jinja2 中访问它们

问题描述 投票:0回答:2

我有 30 到 40 个 SQL 查询,我想使用 jinja2 模板文件来存储查询,以便将 python 代码和 SQL 查询分开存储

对于每个 SQL 查询,我创建一个单独的模板文件并使用下面给出的 python 代码加载该模板

from jinja2 import Environment, FileSystemLoader
    
def main():
    file_loader = FileSystemLoader('path to templates')

    template_group = Environment(loader=file_loader)

    select_template = template_group.get_template("select_query.txt")

    print(select_template.render())

select_query.txt的内容是

select * from employee.details where department="cse"

这对于需要 3 个单独模板文件的 3 个查询来说没问题,但我有 30 到 40 个查询,并且将来可能会增加,

有没有办法将所有 SQL 查询放在一个模板文件中并从 python 代码访问这些查询

提前致谢

python python-3.x python-2.7 templates jinja2
2个回答
0
投票

您应该创建一个文件,将模板存储为 .py 文件,而不是 txt,因为您想将其导入到您的应用程序文件中。 然后您可以创建一个用于存储基本 SQL 模板的变量。此 SQL 模板可以包含占位符,因此您可以将类似的查询压缩为单个查询。例如:


sum_emails_by_event = """
SELECT
    date_,
    {%- for event in events %}
    SUM(CASE WHEN event_type = '{{event}}' THEN 1 END) AS num_{{event}}
    {%- if not loop.last -%}
        , 
    {%- endif -%}
    {%- endfor %}
FROM raw_events
GROUP BY 1
ORDER BY 1 ASC
"""

print(Template(sum_emails_by_event).render(events=['send', 'deliver', 'open', 'click']))

此代码将循环遍历事件列表并为事件列表的每个项目创建 SUM 语句。如果您只是将它们存储在 txt 文件中,则必须存储此查询的大量不同变体。


0
投票

如果您想按照问题评论的建议不使用 django 来执行此操作,您可以将 SQL 查询放入由 jinja2 宏组织的一个文件中:

path_to_templates/queries.j2

{% macro cse_employees() %}
    select * from employee.details where department="cse"
{% endmacro %}

{% macro best_employees() %}
    select * from employee.details where hot=1
{% endmacro %}

..., etc.

然后您可以即时创建必要的模板:

from jinja2 import Environment, FileSystemLoader

loader = FileSystemLoader(path_to_templates)
env = Environment(loader=loader)

# let's say we want to call best_employees()
macro = 'best_employees'

# doubled up on the braces on jinja2's expression delimiter
# to escape python f-string's braces
template_import = '{% import "queries.j2" as queries with context %}\n'
template_main = f'{{{{ queries.{macro}()  }}}}'
template_str = template_import + template_main
template = env.from_string(template_str)

# populate if your sql macros have context to be rendered
context = {}

print(template.render(context))
© www.soinside.com 2019 - 2024. All rights reserved.