Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added docs/examples/usage/__init__.py
Empty file.
18 changes: 18 additions & 0 deletions docs/examples/usage/test_data_flow_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""Example 1: Direct SQL Creation with positional and named parameters."""


def test_direct_sql_creation() -> None:
"""Test creating SQL statements with different parameter styles."""
# start-example
from sqlspec.core.statement import SQL

# Raw SQL string with positional parameters
sql = SQL("SELECT * FROM users WHERE id = ?", 1)

# Named parameters
sql = SQL("SELECT * FROM users WHERE email = :email", email="user@example.com")
# end-example

# Verify SQL objects were created
assert sql is not None

23 changes: 23 additions & 0 deletions docs/examples/usage/test_data_flow_10.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Example 10: SQLite Driver Execution implementation."""


def test_sqlite_driver_pattern() -> None:
"""Test SQLite driver execution pattern."""
# start-example
from sqlspec.driver._sync import SyncDriverAdapterBase

class SqliteDriver(SyncDriverAdapterBase):
def _execute_statement(self, cursor, statement):
sql, params = self._get_compiled_sql(statement)
cursor.execute(sql, params or ())
return self.create_execution_result(cursor)

def _execute_many(self, cursor, statement):
sql, params = self._get_compiled_sql(statement)
cursor.executemany(sql, params)
return self.create_execution_result(cursor)
# end-example

# Verify class was defined
assert SqliteDriver is not None

26 changes: 26 additions & 0 deletions docs/examples/usage/test_data_flow_11.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Example 11: SQLResult Object."""


def test_sql_result_object() -> None:
"""Test accessing SQLResult object properties."""
from sqlspec import SQLSpec
from sqlspec.adapters.sqlite import SqliteConfig

spec = SQLSpec()
config = spec.add_config(SqliteConfig(pool_config={"database": ":memory:"}))

# start-example
with spec.provide_session(config) as session:
result = session.execute("SELECT 'test' as col1, 'value' as col2")

# Access result data
result.data # List of dictionaries
result.rows_affected # Number of rows modified (INSERT/UPDATE/DELETE)
result.column_names # Column names for SELECT
result.operation_type # "SELECT", "INSERT", "UPDATE", "DELETE", "SCRIPT"
# end-example

# Verify result properties
assert result.data is not None
assert result.column_names is not None

34 changes: 34 additions & 0 deletions docs/examples/usage/test_data_flow_12.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Example 12: Convenience Methods."""


def test_convenience_methods() -> None:
"""Test SQLResult convenience methods."""
from sqlspec import SQLSpec
from sqlspec.adapters.sqlite import SqliteConfig

spec = SQLSpec()
config = spec.add_config(SqliteConfig(pool_config={"database": ":memory:"}))

with spec.provide_session(config) as session:
# Create a test table
session.execute("CREATE TABLE test (id INTEGER, name TEXT)")
session.execute("INSERT INTO test VALUES (1, 'Alice')")

# start-example
result = session.execute("SELECT * FROM test WHERE id = 1")

# Get exactly one row (raises if not exactly one)
user = result.one()

# Get one or None
user = result.one_or_none()

# Get scalar value (first column of first row)
result2 = session.execute("SELECT COUNT(*) FROM test")
count = result2.scalar()
# end-example

# Verify results
assert user is not None
assert count == 1

42 changes: 42 additions & 0 deletions docs/examples/usage/test_data_flow_13.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Example 13: Schema Mapping."""


def test_schema_mapping() -> None:
"""Test mapping results to typed objects."""
from sqlspec import SQLSpec
from sqlspec.adapters.sqlite import SqliteConfig

# start-example
from pydantic import BaseModel
from typing import Optional

class User(BaseModel):
id: int
name: str
email: str
is_active: Optional[bool] = True

spec = SQLSpec()
config = spec.add_config(SqliteConfig(pool_config={"database": ":memory:"}))

with spec.provide_session(config) as session:
# Create test table
session.execute("CREATE TABLE users (id INTEGER, name TEXT, email TEXT, is_active INTEGER)")
session.execute("INSERT INTO users VALUES (1, 'Alice', 'alice@example.com', 1)")

# Execute query
result = session.execute("SELECT id, name, email, is_active FROM users")

# Map results to typed User instances
users: list[User] = result.all(schema_type=User)

# Or get single typed user
single_result = session.execute("SELECT id, name, email, is_active FROM users WHERE id = ?", 1)
user: User = single_result.one(schema_type=User) # Type-safe!
# end-example

# Verify typed results
assert len(users) == 1
assert isinstance(user, User)
assert user.id == 1

20 changes: 20 additions & 0 deletions docs/examples/usage/test_data_flow_14.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Example 14: Multi-Tier Caching."""


def test_multi_tier_caching() -> None:
"""Test cache types in SQLSpec."""
# start-example
from sqlglot import Expression

# Cache types and their purposes:
sql_cache: dict[str, str] = {} # Compiled SQL strings
optimized_cache: dict[str, Expression] = {} # Post-optimization AST
builder_cache: dict[str, bytes] = {} # QueryBuilder serialization
file_cache: dict[str, dict] = {} # File loading with checksums
analysis_cache: dict[str, object] = {} # Pipeline step results
# end-example

# Verify cache dictionaries were created
assert isinstance(sql_cache, dict)
assert isinstance(optimized_cache, dict)

27 changes: 27 additions & 0 deletions docs/examples/usage/test_data_flow_15.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Example 15: Configuration-Driven Processing."""


def test_configuration_driven_processing() -> None:
"""Test StatementConfig for controlling pipeline behavior."""
# start-example
from sqlspec.core.statement import StatementConfig
from sqlspec.core.parameters import ParameterStyle, ParameterStyleConfig

config = StatementConfig(
dialect="postgres",
enable_parsing=True, # AST generation
enable_validation=True, # Security/performance checks
enable_transformations=True, # AST transformations
enable_caching=True, # Multi-tier caching
parameter_config=ParameterStyleConfig(
default_parameter_style=ParameterStyle.NUMERIC,
has_native_list_expansion=False,
)
)
# end-example

# Verify config was created
assert config is not None
assert config.dialect == "postgres"
assert config.enable_parsing is True

15 changes: 15 additions & 0 deletions docs/examples/usage/test_data_flow_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Example 2: Using the Query Builder."""


def test_query_builder() -> None:
"""Test building SQL programmatically."""
# start-example
from sqlspec import sql

# Build SQL programmatically
query = sql.select("id", "name", "email").from_("users").where("status = ?", "active")
# end-example

# Verify query object was created
assert query is not None

19 changes: 19 additions & 0 deletions docs/examples/usage/test_data_flow_3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Example 3: From SQL Files."""

from pathlib import Path


def test_sql_file_loader() -> None:
"""Test loading SQL from files."""
# start-example
from sqlspec.loader import SQLFileLoader

loader = SQLFileLoader()
queries_path = Path(__file__).resolve().parents[1] / "queries" / "users.sql"
loader.load_sql(queries_path)
sql = loader.get_sql("get_user_by_id")
# end-example

# Verify SQL object was created
assert sql is not None

18 changes: 18 additions & 0 deletions docs/examples/usage/test_data_flow_4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""Example 4: Parameter Extraction."""


def test_parameter_extraction() -> None:
"""Test parameter extraction and mapping."""
# start-example
# SQLSpec identifies parameter placeholders
# Input: "SELECT * FROM users WHERE id = ? AND status = ?"
# Params: [1, 'active']
#
# Result: Positional parameter mapping created
# Position 0 → value: 1
# Position 1 → value: 'active'
# end-example

# This is a comment example showing the process
pass

18 changes: 18 additions & 0 deletions docs/examples/usage/test_data_flow_5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""Example 5: AST Generation with SQLGlot."""


def test_ast_generation() -> None:
"""Test parsing SQL into Abstract Syntax Tree."""
# start-example
import sqlglot

# Parse SQL into structured AST
expression = sqlglot.parse_one(
"SELECT * FROM users WHERE id = ?",
dialect="sqlite"
)
# end-example

# Verify expression was created
assert expression is not None

17 changes: 17 additions & 0 deletions docs/examples/usage/test_data_flow_6.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Example 6: Compilation to target dialect."""


def test_compilation() -> None:
"""Test compiling AST to target SQL dialect."""
# start-example
import sqlglot

# Compile AST to target dialect
compiled_sql = sqlglot.parse_one("SELECT * FROM users WHERE id = ?", dialect="sqlite").sql(dialect="postgres")
# Result: "SELECT * FROM users WHERE id = $1"
# end-example

# Verify compilation produced a string
assert isinstance(compiled_sql, str)
assert "users" in compiled_sql

14 changes: 14 additions & 0 deletions docs/examples/usage/test_data_flow_7.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Example 7: Parameter Processing."""


def test_parameter_processing() -> None:
"""Test parameter conversion for different database styles."""
# start-example
# Input parameters: [1, 'active']
# Target style: PostgreSQL numeric ($1, $2)
# Result: Parameters ready for execution
# end-example

# This is a comment example showing the process
pass

14 changes: 14 additions & 0 deletions docs/examples/usage/test_data_flow_8.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Example 8: Statement Execution."""


def test_statement_execution() -> None:
"""Test executing compiled SQL with parameters."""
# start-example
# Driver executes compiled SQL with parameters
# cursor.execute(compiled_sql, parameters)
# results = cursor.fetchall()
# end-example

# This is a comment example showing the process
pass

19 changes: 19 additions & 0 deletions docs/examples/usage/test_data_flow_9.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Example 9: Driver Execution with session."""


def test_driver_execution() -> None:
"""Test driver execution pattern."""
from sqlspec import SQLSpec
from sqlspec.adapters.sqlite import SqliteConfig

# start-example
# Driver receives compiled SQL and parameters
spec = SQLSpec()
config = spec.add_config(SqliteConfig(pool_config={"database": ":memory:"}))
with spec.provide_session(config) as session:
result = session.execute("SELECT 'test' as message")
# end-example

# Verify result was returned
assert result is not None

Loading
Loading