API Reference

This section contains the auto-generated API documentation.

sqlo - A modern, type-safe, and extensible SQL query builder for Python.

class sqlo.Q[source]

Bases: object

Query Builder Factory.

static delete_from(table)[source]
Parameters:

table (str)

Return type:

DeleteQuery

classmethod get_dialect()[source]

Get the current default dialect.

static insert_into(table)[source]
Parameters:

table (str)

Return type:

InsertQuery

static raw(sql, params=None)[source]
Parameters:
Return type:

Raw

static select(*columns)[source]
Parameters:

columns (str | Raw | Func)

Return type:

SelectQuery[Any]

classmethod set_debug(debug=True)[source]

Enable or disable debug mode (prints SQL to stdout).

Parameters:

debug (bool)

classmethod set_dialect(dialect)[source]

Set the default dialect for all queries.

static update(table)[source]
Parameters:

table (str)

Return type:

UpdateQuery

class sqlo.Raw(sql, params=None)[source]

Bases: Expression

Raw SQL fragment.

WARNING: Raw SQL bypasses parameter binding and can be vulnerable to SQL injection. Only use Raw() with trusted input or when you need to reference columns/functions.

For dynamic user input, always use parameterized queries instead.

Parameters:
class sqlo.Func(name, *args)[source]

Bases: Expression

Represents a SQL function call.

This class allows you to wrap any SQL function (e.g., COUNT, MAX, AVG, custom functions) and use it within your queries. It supports arguments and aliasing.

Parameters:
  • name (str) – The name of the SQL function (e.g., “COUNT”).

  • *args (Any) – Arguments to pass to the function.

Example

>>> f = Func("COUNT", "*")
>>> f.as_("total")
over(window=None)[source]

Create a window function with OVER clause.

Parameters:

window (Any | None) – Optional Window object for PARTITION BY / ORDER BY

Returns:

WindowFunc object

Return type:

Any

Example

>>> func.row_number().over(Window.partition_by("dept"))
class sqlo.Condition(column=None, value=None, operator='=')[source]

Bases: Expression

Represents a SQL condition for use in WHERE or HAVING clauses.

This class allows you to build simple or complex conditions with support for compact operator syntax (e.g., “age>”) and standard syntax (e.g., “age >”). Conditions can be combined using bitwise operators (& and |) or static methods.

Parameters:
  • column (str, optional) – Column name with optional operator (e.g., “age>=” or “age >=”).

  • value (Any, optional) – The value to compare against. Can be a list for IN operator.

  • operator (str, optional) – The comparison operator if not included in column. Defaults to “=”.

Examples

>>> # Simple condition
>>> c = Condition("age>=", 18)
>>> sql, params = c.build()
>>>
>>> # IN operator
>>> c = Condition("status", ["pending", "done"], operator="IN")
>>>
>>> # IS NULL
>>> c = Condition("deleted_at", operator="IS NULL")
>>>
>>> # Static factory methods
>>> c = Condition.null("deleted_at")
>>> c = Condition.in_("status", ["pending", "done"])
>>> c = Condition.exists(subquery)
>>>
>>> # Combining conditions
>>> c1 = Condition("age>=", 18)
>>> c2 = Condition("country", "US")
>>> combined = c1 & c2  # AND
>>> combined = c1 \| c2  # OR
static and_(*conditions)[source]

Combine multiple conditions with AND logic.

Parameters:

*conditions (Condition) – Variable number of Condition objects

Returns:

Combined Condition object

Return type:

Condition

Example

>>> c1 = Condition("age>=", 18)
>>> c2 = Condition("country", "US")
>>> c3 = Condition("verified", True)
>>> combined = Condition.and_(c1, c2, c3)
>>> # SQL: (`age` >= ? AND `country` = ? AND `verified` = ?)
build(dialect=None)[source]

Build the condition and return (sql, params) tuple.

Parameters:

dialect – Optional dialect to use for quoting. Defaults to MySQLDialect.

Returns:

Tuple of (sql_string, params_tuple)

Return type:

tuple[str, tuple[Any, …]]

Example

>>> c = Condition("age>=", 18)
>>> sql, params = c.build()
>>> assert sql == "`age` >= ?"
>>> assert params == (18,)
static exists(subquery)[source]

Create an EXISTS condition with a subquery.

Parameters:

subquery (SelectQuery) – SelectQuery object

Returns:

Condition object

Return type:

Condition

Example

>>> subquery = Q.select("1").from_("orders").where(Condition("user_id", 123))
>>> c = Condition.exists(subquery)
>>> sql, params = c.build()
>>> # SQL: EXISTS (SELECT 1 FROM `orders` WHERE `user_id` = ?)
static in_(column, values)[source]

Create an IN condition.

Parameters:
Returns:

Condition object

Return type:

Condition

Example

>>> c = Condition.in_("status", ["pending", "done"])
>>> sql, params = c.build()
>>> # SQL: `status` IN (?, ?)
static not_exists(subquery)[source]

Create a NOT EXISTS condition with a subquery.

Parameters:

subquery (SelectQuery) – SelectQuery object

Returns:

Condition object

Return type:

Condition

Example

>>> subquery = Q.select("1").from_("orders").where(Condition("user_id", 123))
>>> c = Condition.not_exists(subquery)
>>> sql, params = c.build()
>>> # SQL: NOT EXISTS (SELECT 1 FROM `orders` WHERE `user_id` = ?)
static not_in(column, values)[source]

Create a NOT IN condition.

Parameters:
Returns:

Condition object

Return type:

Condition

Example

>>> c = Condition.not_in("status", ["canceled", "failed"])
>>> sql, params = c.build()
>>> # SQL: `status` NOT IN (?, ?)
static not_null(column)[source]

Create an IS NOT NULL condition.

Parameters:

column (str) – Column name to check for NOT NULL

Returns:

Condition object

Return type:

Condition

Example

>>> c = Condition.not_null("email")
>>> sql, params = c.build()
>>> # SQL: `email` IS NOT NULL
static null(column)[source]

Create an IS NULL condition.

Parameters:

column (str) – Column name to check for NULL

Returns:

Condition object

Return type:

Condition

Example

>>> c = Condition.null("deleted_at")
>>> sql, params = c.build()
>>> # SQL: `deleted_at` IS NULL
static or_(*conditions)[source]

Combine multiple conditions with OR logic.

Parameters:

*conditions (Condition) – Variable number of Condition objects

Returns:

ComplexCondition object

Return type:

Condition | ComplexCondition

Example

>>> c1 = Condition("status", "pending")
>>> c2 = Condition("status", "processing")
>>> combined = Condition.or_(c1, c2)
>>> # SQL: (`status` = ? OR `status` = ?)
class sqlo.JSON(column)[source]

Bases: Expression

Represents a JSON column.

Example

>>> JSON("data").extract("name")
Parameters:

column (str)

extract(path)[source]

Extract a value from the JSON column.

Parameters:

path (str)

Return type:

JSONPath

class sqlo.JSONPath(column, path)[source]

Bases: Expression

Represents a JSON path extraction.

Parameters:
class sqlo.Window[source]

Bases: object

Represents a SQL window specification for window functions.

Example

>>> Window.partition_by("department").order_by("-salary")
>>> Window.order_by("date").rows_between("UNBOUNDED PRECEDING", "CURRENT ROW")
and_order_by(*columns)[source]

Add ORDER BY clause to the window.

Parameters:

columns (str)

Return type:

Window

and_partition_by(*columns)[source]

Add PARTITION BY clause to the window.

Parameters:

columns (str)

Return type:

Window

build(dialect)[source]

Build the window specification SQL.

Parameters:

dialect (Any)

Return type:

str

classmethod order_by(*columns)[source]

Create a window with ORDER BY clause.

Parameters:

columns (str)

Return type:

Window

classmethod partition_by(*columns)[source]

Create a window with PARTITION BY clause.

Parameters:

columns (str)

Return type:

Window

range_between(start, end)[source]

Add RANGE BETWEEN frame clause.

Parameters:
  • start (str) – Start of the frame

  • end (str) – End of the frame

Return type:

Window

rows_between(start, end)[source]

Add ROWS BETWEEN frame clause.

Parameters:
  • start (str) – Start of the frame (e.g., “UNBOUNDED PRECEDING”, “1 PRECEDING”, “CURRENT ROW”)

  • end (str) – End of the frame (e.g., “CURRENT ROW”, “1 FOLLOWING”, “UNBOUNDED FOLLOWING”)

Return type:

Window

class sqlo.query.select.SelectQuery(*columns, dialect=None, debug=False)[source]

Bases: WhereClauseMixin, Query, Generic[T]

Parameters:

columns (str | Raw | Func | list)

from_(table, alias=None)[source]
Parameters:
Return type:

SelectQuery

join(table, on=None, join_type='INNER')[source]
Parameters:
  • table (str)

  • on (str | None)

  • join_type (str)

Return type:

SelectQuery

inner_join(table, on=None)[source]
Parameters:
Return type:

SelectQuery[T]

left_join(table, on=None)[source]
Parameters:
Return type:

SelectQuery[T]

right_join(table, on=None)[source]
Parameters:
Return type:

SelectQuery[T]

cross_join(table)[source]
Parameters:

table (str)

Return type:

SelectQuery[T]

where(column, value=None, operator='=')[source]
Parameters:
Return type:

SelectQuery[T]

where_in(column, values)[source]

Add an IN WHERE condition.

Parameters:
Return type:

SelectQuery[T]

where_not_in(column, values)[source]

Add a NOT IN WHERE condition.

Parameters:
Return type:

SelectQuery[T]

or_where(column, value=None, operator='=')[source]

Add an OR WHERE condition.

Parameters:
Return type:

SelectQuery[T]

where_null(column)[source]

Add an IS NULL WHERE condition.

Parameters:

column (str)

Return type:

SelectQuery[T]

where_not_null(column)[source]

Add an IS NOT NULL WHERE condition.

Parameters:

column (str)

Return type:

SelectQuery[T]

where_between(column, value1, value2)[source]

Add a BETWEEN WHERE condition.

Parameters:
Return type:

SelectQuery[T]

where_not_between(column, value1, value2)[source]

Add a NOT BETWEEN WHERE condition.

Parameters:
Return type:

SelectQuery[T]

where_like(column, pattern)[source]

Add a LIKE WHERE condition.

Parameters:
Return type:

SelectQuery[T]

where_not_like(column, pattern)[source]

Add a NOT LIKE WHERE condition.

Parameters:
Return type:

SelectQuery[T]

order_by(*columns)[source]
Parameters:

columns (str | Raw)

Return type:

SelectQuery[T]

limit(limit)[source]
Parameters:

limit (int)

Return type:

SelectQuery[T]

offset(offset)[source]
Parameters:

offset (int)

Return type:

SelectQuery[T]

group_by(*columns)[source]
Parameters:

columns (str)

Return type:

SelectQuery[T]

when(condition, callback)[source]
Parameters:
Return type:

SelectQuery[T]

paginate(page, per_page)[source]
Parameters:
Return type:

SelectQuery

force_index(*indexes)[source]
Parameters:

indexes (str)

Return type:

SelectQuery

use_index(*indexes)[source]
Parameters:

indexes (str)

Return type:

SelectQuery

ignore_index(*indexes)[source]
Parameters:

indexes (str)

Return type:

SelectQuery

optimizer_hint(hint)[source]

Add an optimizer hint (MySQL 8.0+).

Parameters:

hint (str)

Return type:

SelectQuery

explain()[source]
Return type:

SelectQuery

distinct()[source]
Return type:

SelectQuery

having(column, value=None, operator='=')[source]
Parameters:
Return type:

SelectQuery

union(query)[source]
Parameters:

query (SelectQuery)

Return type:

SelectQuery[T]

union_all(query)[source]
Parameters:

query (SelectQuery)

Return type:

SelectQuery[T]

as_(alias)[source]

Set an alias for this query (used in FROM clauses).

Parameters:

alias (str)

Return type:

SelectQuery

build()[source]

Build the query and return (sql, params).

Return type:

tuple[str, tuple[Any, …]]

class sqlo.query.insert.InsertQuery(table, dialect=None, debug=False)[source]

Bases: Query

Parameters:

table (str)

values(values)[source]
Parameters:

values (dict[str, Any] | list[dict[str, Any]])

Return type:

InsertQuery

ignore()[source]
Return type:

InsertQuery

on_duplicate_key_update(values)[source]
Parameters:

values (dict[str, Any])

Return type:

InsertQuery

from_select(columns, select_query)[source]

Insert data from a SELECT query.

Parameters:
Return type:

InsertQuery

build()[source]

Build the query and return (sql, params).

Return type:

tuple[str, tuple[Any, …]]

class sqlo.query.update.UpdateQuery(table, dialect=None, debug=False)[source]

Bases: WhereClauseMixin, Query

Parameters:

table (str)

set(values)[source]
Parameters:

values (dict[str, Any])

Return type:

UpdateQuery

join(table, on=None, join_type='INNER')[source]

Add a JOIN clause (MySQL multi-table UPDATE).

Parameters:
  • table (str)

  • on (str | None)

  • join_type (str)

Return type:

UpdateQuery

left_join(table, on=None)[source]

Add a LEFT JOIN clause.

Parameters:
Return type:

UpdateQuery

where(column, value=None, operator='=')[source]
Parameters:
Return type:

UpdateQuery

limit(limit)[source]
Parameters:

limit (int)

Return type:

UpdateQuery

order_by(*columns)[source]
Parameters:

columns (str)

Return type:

UpdateQuery

allow_all_rows()[source]

Allow UPDATE without WHERE clause (updates all rows).

This is a safety feature to prevent accidental mass updates. You must call this method explicitly if you want to update all rows.

Returns:

Self for method chaining

Return type:

UpdateQuery

Example

>>> Q.update("users").set({"active": False}).allow_all_rows().build()
batch_update(values, key)[source]

Perform a batch update using CASE WHEN.

Parameters:
  • values (list[dict[str, Any]]) – List of dictionaries containing values to update. Each dictionary must contain the key column.

  • key (str) – The column name to use as the key (e.g., “id”).

Return type:

UpdateQuery

build()[source]

Build the query and return (sql, params).

Return type:

tuple[str, tuple[Any, …]]

class sqlo.query.delete.DeleteQuery(table, dialect=None, debug=False)[source]

Bases: WhereClauseMixin, Query

Parameters:

table (str)

join(table, on=None, join_type='INNER')[source]

Add a JOIN clause (MySQL multi-table DELETE).

Parameters:
  • table (str)

  • on (str | None)

  • join_type (str)

Return type:

DeleteQuery

left_join(table, on=None)[source]

Add a LEFT JOIN clause.

Parameters:
Return type:

DeleteQuery

where(column, value=None, operator='=')[source]
Parameters:
Return type:

DeleteQuery

limit(limit)[source]
Parameters:

limit (int)

Return type:

DeleteQuery

order_by(*columns)[source]
Parameters:

columns (str)

Return type:

DeleteQuery

allow_all_rows()[source]

Allow DELETE without WHERE clause (deletes all rows).

This is a safety feature to prevent accidental mass deletions. You must call this method explicitly if you want to delete all rows.

Returns:

Self for method chaining

Return type:

DeleteQuery

Example

>>> Q.delete_from("temp_table").allow_all_rows().build()
build()[source]

Build the query and return (sql, params).

Return type:

tuple[str, tuple[Any, …]]

class sqlo.expressions.Expression[source]

Bases: object

Base class for SQL expressions.

alias: str | None = None
as_(alias)[source]

Set an alias for the expression.

Parameters:

alias (str)

Return type:

Expression

class sqlo.expressions.Raw(sql, params=None)[source]

Bases: Expression

Raw SQL fragment.

WARNING: Raw SQL bypasses parameter binding and can be vulnerable to SQL injection. Only use Raw() with trusted input or when you need to reference columns/functions.

For dynamic user input, always use parameterized queries instead.

Parameters:
class sqlo.expressions.Func(name, *args)[source]

Bases: Expression

Represents a SQL function call.

This class allows you to wrap any SQL function (e.g., COUNT, MAX, AVG, custom functions) and use it within your queries. It supports arguments and aliasing.

Parameters:
  • name (str) – The name of the SQL function (e.g., “COUNT”).

  • *args (Any) – Arguments to pass to the function.

Example

>>> f = Func("COUNT", "*")
>>> f.as_("total")
over(window=None)[source]

Create a window function with OVER clause.

Parameters:

window (Any | None) – Optional Window object for PARTITION BY / ORDER BY

Returns:

WindowFunc object

Return type:

Any

Example

>>> func.row_number().over(Window.partition_by("dept"))
class sqlo.expressions.FunctionFactory[source]

Bases: object

Factory for creating SQL function expressions.

static count(expression='*')[source]
Parameters:

expression (str)

Return type:

Func

static sum(expression)[source]
Parameters:

expression (str)

Return type:

Func

static avg(expression)[source]
Parameters:

expression (str)

Return type:

Func

static min(expression)[source]
Parameters:

expression (str)

Return type:

Func

static max(expression)[source]
Parameters:

expression (str)

Return type:

Func

class sqlo.expressions.Condition(column=None, value=None, operator='=')[source]

Bases: Expression

Represents a SQL condition for use in WHERE or HAVING clauses.

This class allows you to build simple or complex conditions with support for compact operator syntax (e.g., “age>”) and standard syntax (e.g., “age >”). Conditions can be combined using bitwise operators (& and |) or static methods.

Parameters:
  • column (str, optional) – Column name with optional operator (e.g., “age>=” or “age >=”).

  • value (Any, optional) – The value to compare against. Can be a list for IN operator.

  • operator (str, optional) – The comparison operator if not included in column. Defaults to “=”.

Examples

>>> # Simple condition
>>> c = Condition("age>=", 18)
>>> sql, params = c.build()
>>>
>>> # IN operator
>>> c = Condition("status", ["pending", "done"], operator="IN")
>>>
>>> # IS NULL
>>> c = Condition("deleted_at", operator="IS NULL")
>>>
>>> # Static factory methods
>>> c = Condition.null("deleted_at")
>>> c = Condition.in_("status", ["pending", "done"])
>>> c = Condition.exists(subquery)
>>>
>>> # Combining conditions
>>> c1 = Condition("age>=", 18)
>>> c2 = Condition("country", "US")
>>> combined = c1 & c2  # AND
>>> combined = c1 \| c2  # OR
build(dialect=None)[source]

Build the condition and return (sql, params) tuple.

Parameters:

dialect – Optional dialect to use for quoting. Defaults to MySQLDialect.

Returns:

Tuple of (sql_string, params_tuple)

Return type:

tuple[str, tuple[Any, …]]

Example

>>> c = Condition("age>=", 18)
>>> sql, params = c.build()
>>> assert sql == "`age` >= ?"
>>> assert params == (18,)
static null(column)[source]

Create an IS NULL condition.

Parameters:

column (str) – Column name to check for NULL

Returns:

Condition object

Return type:

Condition

Example

>>> c = Condition.null("deleted_at")
>>> sql, params = c.build()
>>> # SQL: `deleted_at` IS NULL
static not_null(column)[source]

Create an IS NOT NULL condition.

Parameters:

column (str) – Column name to check for NOT NULL

Returns:

Condition object

Return type:

Condition

Example

>>> c = Condition.not_null("email")
>>> sql, params = c.build()
>>> # SQL: `email` IS NOT NULL
static in_(column, values)[source]

Create an IN condition.

Parameters:
Returns:

Condition object

Return type:

Condition

Example

>>> c = Condition.in_("status", ["pending", "done"])
>>> sql, params = c.build()
>>> # SQL: `status` IN (?, ?)
static not_in(column, values)[source]

Create a NOT IN condition.

Parameters:
Returns:

Condition object

Return type:

Condition

Example

>>> c = Condition.not_in("status", ["canceled", "failed"])
>>> sql, params = c.build()
>>> # SQL: `status` NOT IN (?, ?)
static exists(subquery)[source]

Create an EXISTS condition with a subquery.

Parameters:

subquery (SelectQuery) – SelectQuery object

Returns:

Condition object

Return type:

Condition

Example

>>> subquery = Q.select("1").from_("orders").where(Condition("user_id", 123))
>>> c = Condition.exists(subquery)
>>> sql, params = c.build()
>>> # SQL: EXISTS (SELECT 1 FROM `orders` WHERE `user_id` = ?)
static not_exists(subquery)[source]

Create a NOT EXISTS condition with a subquery.

Parameters:

subquery (SelectQuery) – SelectQuery object

Returns:

Condition object

Return type:

Condition

Example

>>> subquery = Q.select("1").from_("orders").where(Condition("user_id", 123))
>>> c = Condition.not_exists(subquery)
>>> sql, params = c.build()
>>> # SQL: NOT EXISTS (SELECT 1 FROM `orders` WHERE `user_id` = ?)
static and_(*conditions)[source]

Combine multiple conditions with AND logic.

Parameters:

*conditions (Condition) – Variable number of Condition objects

Returns:

Combined Condition object

Return type:

Condition

Example

>>> c1 = Condition("age>=", 18)
>>> c2 = Condition("country", "US")
>>> c3 = Condition("verified", True)
>>> combined = Condition.and_(c1, c2, c3)
>>> # SQL: (`age` >= ? AND `country` = ? AND `verified` = ?)
static or_(*conditions)[source]

Combine multiple conditions with OR logic.

Parameters:

*conditions (Condition) – Variable number of Condition objects

Returns:

ComplexCondition object

Return type:

Condition | ComplexCondition

Example

>>> c1 = Condition("status", "pending")
>>> c2 = Condition("status", "processing")
>>> combined = Condition.or_(c1, c2)
>>> # SQL: (`status` = ? OR `status` = ?)
class sqlo.expressions.ComplexCondition(operator, left, right)[source]

Bases: Expression

Represents a complex SQL condition combining multiple conditions with AND/OR logic.

This class is typically created automatically when using bitwise operators (& or |) on Condition objects, or when using Condition.and_() / Condition.or_() static methods. It properly handles operator precedence and nested conditions.

Parameters:

Examples

>>> c1 = Condition("age>=", 18)
>>> c2 = Condition("country", "US")
>>> c3 = Condition("verified", True)
>>>
>>> # Creates ComplexCondition automatically
>>> complex = (c1 & c2) \| c3
>>> # Represents: (age >= 18 AND country = 'US') OR verified = True
build(dialect=None)[source]

Build the complex condition and return (sql, params) tuple.

Parameters:

dialect – Optional dialect to use for quoting. Defaults to MySQLDialect.

Returns:

Tuple of (sql_string, params_tuple)

Return type:

tuple[str, tuple[Any, …]]

Example

>>> c1 = Condition("age>=", 18)
>>> c2 = Condition("country", "US")
>>> complex = c1 \| c2
>>> sql, params = complex.build()
>>> # SQL: (`age` >= ? OR `country` = ?)
class sqlo.expressions.JSONPath(column, path)[source]

Bases: Expression

Represents a JSON path extraction.

Parameters:
class sqlo.expressions.JSON(column)[source]

Bases: Expression

Represents a JSON column.

Example

>>> JSON("data").extract("name")
Parameters:

column (str)

extract(path)[source]

Extract a value from the JSON column.

Parameters:

path (str)

Return type:

JSONPath