Usage¶
This guide covers advanced features of the SQLFileLoader and aiosql adapter.
SQLFileLoader (Built-in)¶
For detailed SQLFileLoader documentation, see SQL File Loader.
Key features covered here:
SQL file format
Cloud storage loading
Type-safe results
Query introspection
Cache management
SQL File Format¶
Basic query definition:
-- name: query_name
SELECT * FROM users WHERE id = :user_id;
With documentation:
-- name: get_active_users
-- Retrieve all active users from the database.
-- This query excludes soft-deleted users.
SELECT id, username, email
FROM users
WHERE is_active = true AND deleted_at IS NULL
ORDER BY username;
Dialect-specific queries:
-- name: upsert_user
-- dialect: postgres
INSERT INTO users (id, name) VALUES (:id, :name)
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name;
Cloud Storage Support¶
Load SQL files from cloud storage:
from sqlspec import SQLSpec
spec = SQLSpec()
# Amazon S3
spec.load_sql_files("s3://my-bucket/queries/users.sql")
# Google Cloud Storage
spec.load_sql_files("gs://my-bucket/queries/users.sql")
# Azure Blob Storage
spec.load_sql_files("az://my-container/queries/users.sql")
# HTTP/HTTPS
spec.load_sql_files("https://example.com/queries/users.sql")
Type-Safe Results¶
Combine with schema mapping:
from pydantic import BaseModel
class User(BaseModel):
id: int
username: str
email: str
async with spec.provide_session(config) as session:
result = await session.execute(
spec.get_sql("get_user_by_id"),
user_id=1,
schema_type=User
)
user: User = result.one()
Query Introspection¶
# List all queries
queries = spec.list_sql_queries()
# Check if query exists
if spec.has_sql_query("get_user"):
print("Query exists!")
# Get SQL files
files = spec.get_sql_files()
print(f"Loaded files: {files}")
Cache Management¶
# Clear all caches
spec.clear_sql_cache()
# Reload SQL files
spec.reload_sql_files()
aiosql Adapter¶
Query Operators¶
The aiosql adapter supports all aiosql query operators:
Operator |
Meaning |
Example |
|---|---|---|
(none) |
Select many (list of rows) |
|
|
Select one (single row or None) |
|
|
Select value (single value) |
|
|
Insert/Update/Delete |
|
|
Insert/Update/Delete many |
|
|
Script (no return) |
|
Example SQL file:
-- name: get_all_users
SELECT id, username FROM users;
-- name: get_user_by_id^
SELECT id, username FROM users WHERE id = :user_id;
-- name: count_users$
SELECT COUNT(*) FROM users;
-- name: create_user!
INSERT INTO users (username) VALUES (:username);
-- name: bulk_create*!
INSERT INTO users (username) VALUES (:username);
-- name: create_tables#
CREATE TABLE users (id SERIAL, username TEXT);
Usage:
# Select many
users = queries.get_all_users(conn)
# Select one
user = queries.get_user_by_id(conn, user_id=1)
# Select value
count = queries.count_users(conn)
# Insert/Update/Delete
queries.create_user(conn, username="alice")
# Bulk operations
queries.bulk_create(conn, [{"username": "user1"}, {"username": "user2"}])
# Script
queries.create_tables(conn)
Transaction Support¶
# Async transactions
async with spec.provide_session(config) as session:
async with session.begin_transaction():
await queries.create_user(session.connection, username="alice")
await queries.create_user(session.connection, username="bob")
Type Mapping¶
Limited type mapping via special parameter:
from pydantic import BaseModel
class User(BaseModel):
id: int
username: str
result = queries.get_all_users(conn, _sqlspec_schema_type=User)
Best Practices¶
Organize by Domain¶
queries/
users.sql # User management
products.sql # Product catalog
orders.sql # Order processing
analytics.sql # Reports
Use Clear Query Names¶
-- Good
-- name: get_active_users_by_role
-- name: create_order_with_items
-- Bad
-- name: query1
-- name: get_data
Document Complex Queries¶
-- name: calculate_inventory
-- Calculate current inventory accounting for pending orders.
-- Returns items below reorder threshold.
SELECT
p.id,
p.current_stock - COALESCE(SUM(oi.quantity), 0) as available
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
WHERE available < p.reorder_point;
Use Parameters¶
-- Good: Safe from SQL injection
-- name: get_user_by_email
SELECT * FROM users WHERE email = :email;
-- Bad: Never do this
SELECT * FROM users WHERE email = '{email}';
See Also¶
SQL File Loader - Complete SQL file loader guide
Quick Start - Get started quickly
Compatibility Guide - Using aiosql files with SQLSpec
API Reference - API reference