SQL Templating
flAPI uses Mustache templating to create dynamic, parameterized SQL queries. This approach, inspired by dbt, is immediately familiar to data analysts and data scientists while providing powerful flexibility.
How Template Processing Works
Why Templates?
Instead of writing separate SQL for every possible query combination, write one template that adapts:
-- ❌ Without templates: Multiple queries
SELECT * FROM customers WHERE country = 'US';
SELECT * FROM customers WHERE country = 'DE';
SELECT * FROM customers WHERE country = 'FR' AND segment = 'ENTERPRISE';
-- ... hundreds of combinations
-- ✅ With templates: One query
SELECT * FROM customers
WHERE 1=1
{{#params.country}}
AND country = '{{{params.country}}}'
{{/params.country}}
{{#params.segment}}
AND segment = '{{{params.segment}}}'
{{/params.segment}}
Basic Syntax
Variable Insertion
Use {{{ }}}
(triple braces) for safe variable insertion:
-- Template
SELECT * FROM customers
WHERE customer_id = {{{params.id}}}
-- With params: {"id": 12345}
SELECT * FROM customers
WHERE customer_id = 12345
Important: Triple braces {{{ }}}
prevent HTML escaping and are safe for SQL when combined with flAPI's parameter validation.
Conditional Blocks
Use {{#variable}}...{{/variable}}
for conditional inclusion:
SELECT * FROM orders
WHERE 1=1
{{#params.status}}
AND status = '{{{params.status}}}'
{{/params.status}}
{{#params.date}}
AND order_date >= '{{{params.date}}}'
{{/params.date}}
When params are provided:
{"status": "completed", "date": "2024-01-01"}
Expands to:
SELECT * FROM orders
WHERE 1=1
AND status = 'completed'
AND order_date >= '2024-01-01'
When params are empty:
{}
Expands to:
SELECT * FROM orders
WHERE 1=1
Negation (Unless)
Use {{^variable}}...{{/variable}}
for "if not" conditions:
SELECT * FROM products
WHERE 1=1
{{^params.include_discontinued}}
AND active = true
{{/params.include_discontinued}}
Context Variables
Request Parameters (params
)
Access query/path/header parameters:
SELECT * FROM customers
WHERE 1=1
{{#params.segment}}
AND market_segment = '{{{params.segment}}}'
{{/params.segment}}
{{#params.min_balance}}
AND account_balance >= {{{params.min_balance}}}
{{/params.min_balance}}
Connection Properties (conn
)
Access connection configuration:
-- Connection defined as:
-- connections:
-- my-data:
-- properties:
-- path: './data/customers.parquet'
SELECT * FROM '{{{conn.path}}}'
WHERE active = true
User Context (context.user
)
Access authenticated user information for row-level security:
SELECT * FROM sales_data
WHERE 1=1
{{#context.user.roles.admin}}
-- Admins see everything
{{/context.user.roles.admin}}
{{^context.user.roles.admin}}
-- Regular users see only their region
AND region = '{{{context.user.region}}}'
AND department = '{{{context.user.department}}}'
{{/context.user.roles.admin}}
Cache Properties (cache
)
When building cache, access cache configuration:
-- In cache template
CREATE OR REPLACE TABLE {{cache.catalog}}.{{cache.schema}}.{{cache.table}} AS
SELECT * FROM source_data;
Environment Variables (env
)
Access whitelisted environment variables:
SELECT * FROM logs
WHERE environment = '{{{env.FLAPI_ENV}}}'
AND region = '{{{env.AWS_REGION}}}'