This document describes the supported public API exposed by sqlbind_t.
The package has two main layers:
- Query construction:
sqlbind_t - Rendering and backend integration:
- Backend dialect:
sqlbind_t.dialect,sqlbind_t.sqlite,sqlbind_t.postgresql - Parameter markers:
sqlbind_t.query_params
- Backend dialect:
Normalized composable SQL fragment. It's a thin wrapper around template strings object
- Iterates over its string and interpolation parts
- Supports boolean-style composition operators:
left & right->AND(...)left | right->OR(...)~fragment->NOT ...
- Falsey only when empty
Use sql() or text() to construct SQL values. Avoid calling SQL(...) directly unless you are extending the library at a low level.
Empty SQL fragment.
Many helpers return EMPTY when all inputs are omitted.
Template type used by the library.
- On Python 3.14+, this is
string.templatelib.Template - On older Python versions,
sqlbind_tprovides a compatible implementation - Produced implicitly by native t-strings and by the tf-string compatibility layer
Application code usually receives this type implicitly and rarely needs to instantiate it directly.
Interpolation part type used inside Template and SQL.
Sentinel type used to mark omitted conditional values.
Most code should use the singleton UNDEFINED instead of constructing UndefinedType directly.
Singleton sentinel used by conditional helpers such as not_none, truthy, cond, and required.
When a template contains an interpolation with UNDEFINED, that template renders as an empty fragment.
Trusted identifier/expression builder.
Expr produces SQL text directly and does not quote or validate names.
Construction:
E.name->nameE.table.column->table.columnE('raw expression')-> arbitrary trusted expression text
Supported operators and helpers:
expr < valueexpr <= valueexpr > valueexpr >= valueexpr == valueexpr != value~exprexpr & otherexpr | otherexpr.IN(values)expr.LIKE(pattern, value)expr.ILIKE(pattern, value)expr.ASCexpr.DESC
Special behavior:
expr == NonerendersIS NULLexpr != NonerendersIS NOT NULL- Comparing against
UNDEFINED-producing markers yieldsEMPTY
Shared root Expr instance.
Use E for most expression building:
E.user.email
E.created_at.DESC
E('"weird table"."column"')Type alias for values accepted by most helpers and renderers.
- Equivalent to
SQL | Template - Use it for annotations and helper arguments that accept either a normalized
SQLfragment or a raw template
Type alias for values that are embedded into SQL as trusted SQL text rather than bound as parameters.
- Equivalent to
Expr | AnySQL - Only pass trusted identifiers or trusted SQL fragments through APIs that consume
SafeStr
Wraps trusted static SQL text as a SQL fragment.
- Interpolates nothing
- Does not quote or validate the input
- Only use with trusted SQL text
Example:
text('created_at IS NOT NULL')Normalizes a template-like value into SQL.
- Returns the same object when given
SQL - Returns
EMPTYif the template containsUNDEFINED - Preferred way to convert a t-string or transformed template into
SQL
For python versions older than 3.14.
Builds SQL from a transformed f-string template.
- Intended for tf-string compatibility on Python versions without t-strings
- Expects a transformed string such as
sqlf(f'@SELECT ...') - Raises
RuntimeErrorif called on an untransformed regular string
For python versions older than 3.14.
Parses a template expression from a plain string at runtime.
- Evaluates interpolations using
evalin the caller frame - Useful as a last-resort compatibility fallback when t-strings are unavailable
- Less safe and less type-checker-friendly than t-strings or
sqlf
These helpers omit empty fragments automatically.
Joins non-empty fragments with AND, wrapping the result in parentheses when needed.
Joins non-empty fragments with OR, wrapping the result in parentheses when needed.
Builds a WITH ... clause from non-empty fragments.
Builds a WHERE ... clause.
- Positional arguments are treated as query fragments
- Keyword arguments become equality checks:
value is None->field IS NULL- other values ->
field = ? UNDEFINEDvalues are omitted
- Keyword names are embedded directly into SQL and must be trusted
Builds a GROUP BY ... clause from trusted field expressions.
Builds an ORDER BY ... clause from trusted field expressions.
Builds a SET ... clause.
- Each keyword becomes
field = value UNDEFINEDvalues are omitted- Keyword names are embedded directly into SQL and must be trusted
Builds a (<columns>) VALUES (...) fragment.
- Pass
kwargsfor a single row - Pass
data=[...]for multi-row inserts - Column names are taken from the first row and embedded directly into SQL
- Row dictionaries are expected to have the same keys in the same logical order
Prefixes a non-empty fragment with AND .
Useful when inlining optional filters into a larger statement.
Prefixes a non-empty fragment with OR .
Low-level helper that prefixes a non-empty fragment with arbitrary trusted text.
This is part of the public module surface, but most callers should prefer the dedicated helpers above.
sqlbind_t.join_fragments(sep: str, flist: Sequence[SQL], wrap: tuple[str, str] | None = None, prefix: str = '') -> SQL
Low-level helper used to join already-normalized SQL fragments.
Most callers should use AND, OR, WITH, WHERE, GROUP_BY, ORDER_BY, or SET instead.
Low-level helper that builds comma-separated field = value assignments without the SET prefix.
Prefer SET(...) in application code.
These helpers work through / operator overloading and either return the original value or UNDEFINED.
Omits the value when it is None.
Example:
E.enabled == (not_none / enabled)Omits the value when bool(value) is false.
Factory for explicit conditional markers.
cond(True) / valuereturnsvaluecond(False) / valuereturnsUNDEFINED
Omits the wrapped value when a nested SQL fragment is empty.
Useful for wrappers like:
t'WHERE {required / nested_filter}'Builds a half-open range:
field >= left AND field < right- Omits the left comparison when
left is None - Omits the right comparison when
right is None - Returns
EMPTYwhen both bounds areNone
Builds a closed range:
field >= left AND field <= rightBuilds a dialect-aware IN condition.
UNDEFINEDreturnsEMPTY- Empty collections render as the dialect false expression
- Actual SQL varies by dialect:
- generic:
field IN ? - SQLite: expanded marker or literal list
- PostgreSQL:
field = ANY(...)
- generic:
Builds a LIKE condition with escaping.
- Escapes
%,_, and the dialect escape character in the value templateis a pattern with{}placeholder for the escaped value- Common templates:
'{}%'for startswith'%{}'for endswith'%{}%'for contains
UNDEFINEDreturnsEMPTY
Equivalent to LIKE(..., op='ILIKE').
Whether ILIKE is valid depends on the target backend.
Default renderer that turns AnySQL into (sql_text, params_container).
Important methods:
Renders the query and returns:
- SQL text with backend-specific parameter markers
- The same params container instance, populated during rendering
Behavior:
- If
paramsis omitted, usesQMarkQueryParams - Recursively renders nested templates and
SQLfragments - Handles dialect operations such as
INandLIKE - Emits identifiers from
Exprdirectly
Renders trusted SQL fragments without compiling them as bound parameters.
Useful mainly for dialect implementors.
Default IN rendering.
- Non-empty collections render as
field IN <marker> - Empty collections render as
Dialect.FALSE(FALSEby default)
Default escaped LIKE rendering.
Class attribute used when an operation must render a false expression.
Default value: FALSE
Escape character used by LIKE.
Default value: \\
Characters escaped by LIKE.
Default value: %_
Shortcut for Dialect().render(...).
This is the most convenient renderer when the generic dialect is sufficient.
Escapes a raw value for use inside a SQL LIKE pattern.
Prefer LIKE or Expr.LIKE when you are building a predicate, and use like_escape only when you need manual pattern assembly.
Each class implements a DB-API parameter marker style.
Abstract base class with compile(value) -> str.
Uses ? markers and stores values in a list.
Uses %s markers and stores values in a list.
Uses :1, :2, ... markers and stores values in a list.
Uses $1, $2, ... markers and stores values in a list.
Uses :p0, :p1, ... markers and stores values in a dict.
Uses %(p0)s, %(p1)s, ... markers and stores values in a dict.
List-backed base class for positional parameter styles.
Useful mainly for extension code.
Dict-backed base class for named parameter styles.
Useful mainly for extension code.
SQLite-specific renderer.
Differences from the generic dialect:
FALSEis rendered as0- Short
INlists are expanded tofield IN (?, ?, ...) - Long
INlists are embedded as escaped SQLite literals to avoid parameter-count issues
Threshold used by SQLite IN rendering before switching to literal expansion.
Default value: 10
Escapes a str, int, or float for literal embedding into SQLite SQL.
This is a low-level helper used by the SQLite dialect.
Renders a comma-separated literal list for SQLite IN (...).
This is a low-level helper used by the SQLite dialect.
PostgreSQL-specific renderer.
Difference from the generic dialect:
INis rendered asfield = ANY(array_param)
This is intended to work better with PostgreSQL drivers that do not support IN %s tuple binding directly.