CLI Reference¶
Complete command-line interface reference for FraiseQL. The CLI provides project scaffolding, development server, code generation, and SQL utilities.
Installation¶
The CLI is installed automatically with FraiseQL:
Global Options¶
| Option | Description |
|---|---|
--version |
Show FraiseQL version and exit |
--help |
Show help message and exit |
Commands Overview¶
| Command | Purpose | Use Case |
|---|---|---|
fraiseql init |
Create new project | Starting a new FraiseQL project |
fraiseql dev |
Development server | Local development with hot reload |
fraiseql check |
Validate project | Pre-deployment validation |
fraiseql generate |
Code generation | Schema, migrations, CRUD |
fraiseql sql |
SQL utilities | View generation, patterns, validation |
fraiseql init¶
Initialize a new FraiseQL project with complete directory structure.
Usage¶
Arguments¶
| Argument | Required | Description |
|---|---|---|
PROJECT_NAME |
Yes | Name of the project directory to create |
Options¶
| Option | Default | Description |
|---|---|---|
--template [basic\|blog\|ecommerce] |
basic |
Project template to use |
--database-url TEXT |
postgresql://localhost/mydb |
PostgreSQL connection URL |
--no-git |
Flag | Skip git repository initialization |
Templates¶
basic - Simple User type with minimal setup
- Single src/main.py with User type
- Basic project structure
- Ideal for learning or simple APIs
blog - Complete blog application structure
- User, Post, Comment types in separate files
- Organized src/types/ directory
- Demonstrates relationships and imports
ecommerce - E-commerce application (work in progress) - Currently uses basic template - Future: Product, Order, Customer types
Generated Structure¶
my-project/
├── src/
│ ├── __init__.py
│ ├── main.py # Application entry point
│ ├── types/ # FraiseQL type definitions
│ ├── mutations/ # GraphQL mutations
│ └── queries/ # Custom query logic
├── tests/ # Test files
├── migrations/ # Database migrations
├── .env # Environment variables
├── .gitignore # Git ignore patterns
├── pyproject.toml # Project configuration
└── README.md # Project documentation
Environment Variables¶
The .env file is created with:
FRAISEQL_DATABASE_URL=postgresql://localhost/mydb
FRAISEQL_AUTO_CAMEL_CASE=true
FRAISEQL_DEV_AUTH_PASSWORD=development-only-password
Examples¶
Basic project:
Blog template with custom database:
Skip git initialization:
Next Steps After Init¶
cd PROJECT_NAME
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
fraiseql dev
fraiseql dev¶
Start the development server with hot-reloading enabled.
Usage¶
Options¶
| Option | Default | Description |
|---|---|---|
--host TEXT |
127.0.0.1 |
Host to bind to |
--port INTEGER |
8000 |
Port to bind to |
--reload/--no-reload |
--reload |
Enable auto-reload on code changes |
--app TEXT |
src.main:app |
Application import path (module:attribute) |
Requirements¶
- Must be run from a FraiseQL project directory (contains
pyproject.toml) - Requires
uvicornto be installed - Loads environment variables from
.envif present
Environment Loading¶
Automatically loads .env file if it exists:
📋 Loading environment from .env file
🚀 Starting FraiseQL development server...
GraphQL API: http://127.0.0.1:8000/graphql
Interactive GraphiQL: http://127.0.0.1:8000/graphql
Auto-reload: enabled
Press CTRL+C to stop
Examples¶
Standard development:
Custom host and port:
Disable auto-reload:
Custom app location:
Troubleshooting¶
"Not in a FraiseQL project directory"
- Ensure you're in the project root with pyproject.toml
- Run fraiseql init if starting new project
"uvicorn not installed"
Port already in use
fraiseql check¶
Validate project structure and FraiseQL type definitions.
Usage¶
Validation Steps¶
- Project Structure - Checks for required directories
- ✅
src/directory - ✅
tests/directory -
✅
migrations/directory -
Application File - Validates
src/main.pyexists -
Type Import - Ensures FraiseQL app can be imported
-
Schema Building - Validates GraphQL schema generation
Output¶
🔍 Checking FraiseQL project...
📁 Checking project structure...
✅ src/
✅ tests/
✅ migrations/
🐍 Validating FraiseQL types...
✅ Found FraiseQL app
📊 Registered types: 5
📊 Input types: 3
✅ GraphQL schema builds successfully!
📊 Schema contains 12 custom types
✨ All checks passed!
Exit Codes¶
| Code | Meaning |
|---|---|
0 |
All checks passed |
1 |
Validation failed (check output for details) |
Examples¶
Pre-deployment validation:
CI/CD integration:
Common Issues¶
"No 'app' found in src/main.py"
- Ensure you have: app = fraiseql.create_fraiseql_app(...)
"Schema validation failed" - Check all type definitions for syntax errors - Ensure all referenced types are imported
fraiseql generate¶
Code generation commands for schema, migrations, and CRUD operations.
Usage¶
Subcommands¶
| Command | Purpose |
|---|---|
schema |
Export GraphQL schema file |
migration |
Generate database migration SQL |
crud |
Generate CRUD mutation boilerplate |
generate schema¶
Export GraphQL schema to a file for client-side tooling.
Usage:
Options:
| Option | Default | Description |
|---|---|---|
-o, --output TEXT |
schema.graphql |
Output file path |
Examples:
# Generate schema.graphql
fraiseql generate schema
# Custom output path
fraiseql generate schema -o graphql/schema.graphql
# Use in client code generation
fraiseql generate schema -o schema.graphql
graphql-codegen --schema schema.graphql
Output Format:
type User {
id: ID!
email: String!
name: String!
createdAt: String!
}
type Query {
users: [User!]!
user(id: ID!): User
}
generate migration¶
Generate database migration SQL for a FraiseQL type.
Usage:
Arguments:
| Argument | Required | Description |
|---|---|---|
ENTITY_NAME |
Yes | Name of the entity (e.g., User, Post) |
Options:
| Option | Default | Description |
|---|---|---|
--table TEXT |
{entity_name}s |
Custom table name |
Generated Migration Includes:
- Table creation with JSONB data column
- Indexes on data (GIN), created_at, deleted_at
- Updated_at trigger for automatic timestamp updates
- View creation for FraiseQL queries
- Soft delete support via deleted_at column
Examples:
# Generate migration for User type
fraiseql generate migration User
# Creates: migrations/20241010120000_create_users.sql
# Custom table name
fraiseql generate migration Post --table blog_posts
# Creates: migrations/20241010120000_create_blog_posts.sql
Generated SQL Structure:
-- Create table with JSONB
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
data JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMPTZ
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_users_data ON users USING gin(data);
CREATE INDEX IF NOT EXISTS idx_users_created_at ON users(created_at);
CREATE INDEX IF NOT EXISTS idx_users_deleted_at ON users(deleted_at) WHERE deleted_at IS NULL;
-- Updated_at trigger
CREATE OR REPLACE FUNCTION update_users_updated_at()...
-- View for FraiseQL
CREATE OR REPLACE VIEW v_users AS
SELECT id, data, created_at, updated_at
FROM users
WHERE deleted_at IS NULL;
Apply Migration:
generate crud¶
Generate CRUD mutations boilerplate for a type.
Usage:
Arguments:
| Argument | Required | Description |
|---|---|---|
TYPE_NAME |
Yes | Name of the type (e.g., User, Product) |
Generated Files:
Creates src/mutations/{type_name}_mutations.py with:
- Input types (Create, Update)
- Result types (Success, Error, Result union)
- Mutation functions (create, update, delete)
Examples:
# Generate CRUD for User type
fraiseql generate crud User
# Creates: src/mutations/user_mutations.py
# Generate CRUD for Product type
fraiseql generate crud Product
# Creates: src/mutations/product_mutations.py
Generated Structure:
import fraiseql
from fraiseql.types import ID
@fraiseql.input
class CreateUserInput:
name: str
@input
class UpdateUserInput:
id: ID
name: str | None
@success
class UserSuccess:
user: User
message: str
@error
class UserError:
message: str
code: str
@result
class UserResult:
pass
@fraiseql.mutation
async def create_user(input: CreateUserInput, repository: CQRSRepository) -> UserResult:
# Call your CQRS repository methods
result = await repository.create(input)
return UserResult(user=result)
Next Steps: 1. Import and register mutations in your app 2. Customize input fields and validation logic 3. Implement repository calls with proper error handling
fraiseql sql¶
SQL helper commands for view generation, patterns, and validation.
Usage¶
Subcommands¶
| Command | Purpose |
|---|---|
generate-view |
Generate SQL view for a type |
generate-setup |
Complete SQL setup (table + view + indexes) |
generate-pattern |
Common SQL patterns (pagination, filtering, etc.) |
validate |
Validate SQL for FraiseQL compatibility |
explain |
Explain SQL in beginner-friendly terms |
sql generate-view¶
Generate a SQL view definition from a FraiseQL type.
Usage:
Options:
| Option | Description |
|---|---|
-m, --module TEXT |
Python module containing the type (e.g., src.types) |
-t, --table TEXT |
Custom table name (default: inferred from type) |
-v, --view TEXT |
Custom view name (default: v_{table}) |
-e, --exclude TEXT |
Fields to exclude (can be repeated) |
--with-comments/--no-comments |
Include explanatory comments (default: yes) |
-o, --output FILE |
Output file (default: stdout) |
Examples:
# Generate view for User type
fraiseql sql generate-view User --module src.types
# Exclude sensitive fields
fraiseql sql generate-view User -e password -e secret_token
# Custom table and view names
fraiseql sql generate-view User --table tb_users --view v_user_public
# Save to file
fraiseql sql generate-view User -o migrations/001_user_view.sql
sql generate-setup¶
Generate complete SQL setup including table, indexes, and view.
Usage:
Options:
| Option | Description |
|---|---|
-m, --module TEXT |
Python module containing the type |
--with-table |
Include table creation SQL |
--with-indexes |
Include index creation SQL |
--with-data |
Include sample data INSERT statements |
-o, --output FILE |
Output file path |
Examples:
# Complete setup with table and indexes
fraiseql sql generate-setup User --with-table --with-indexes
# Include sample data for testing
fraiseql sql generate-setup User --with-table --with-indexes --with-data
# Save complete setup
fraiseql sql generate-setup User --with-table --with-indexes -o db/schema.sql
sql generate-pattern¶
Generate common SQL patterns for queries.
Usage:
Pattern Types:
| Pattern | Description | Required Options |
|---|---|---|
pagination |
LIMIT/OFFSET pagination | --limit, --offset |
filtering |
WHERE clause filtering | -w field=value (repeatable) |
sorting |
ORDER BY clause | -o field:direction (repeatable) |
relationship |
JOIN with child table | --child-table, --foreign-key |
aggregation |
GROUP BY with aggregates | --group-by |
Options:
| Option | Description |
|---|---|
--limit INTEGER |
Pagination limit (default: 20) |
--offset INTEGER |
Pagination offset (default: 0) |
-w, --where TEXT |
Filter condition (format: field=value) |
-o, --order TEXT |
Order specification (format: field:direction) |
--child-table TEXT |
Child table for relationships |
--foreign-key TEXT |
Foreign key column name |
--group-by TEXT |
Field to group by |
Examples:
# Pagination pattern
fraiseql sql generate-pattern pagination users --limit 10 --offset 20
# Filtering pattern with multiple conditions
fraiseql sql generate-pattern filtering users \
-w email=test@example.com \
-w is_active=true
# Sorting pattern
fraiseql sql generate-pattern sorting users \
-o name:ASC \
-o created_at:DESC
# Relationship pattern (users with their posts)
fraiseql sql generate-pattern relationship users \
--child-table posts \
--foreign-key user_id
# Aggregation pattern (posts per user)
fraiseql sql generate-pattern aggregation posts --group-by user_id
Generated Output Example (pagination):
sql validate¶
Validate SQL for FraiseQL compatibility.
Usage:
Checks: - View returns JSONB data - Contains 'data' column - Compatible with FraiseQL query patterns
Examples:
# Validate a view definition
fraiseql sql validate migrations/001_user_view.sql
# Output on success:
# ✓ SQL is valid for FraiseQL
# ✓ Has 'data' column
# ✓ Returns JSONB
# Output on failure:
# ✗ SQL has issues:
# - Missing 'data' column
# - Does not return JSONB
sql explain¶
Explain SQL in beginner-friendly terms.
Usage:
Provides: - Human-readable explanation of SQL operations - Common mistake detection - Optimization suggestions
Examples:
fraiseql sql explain migrations/001_user_view.sql
# Output:
# SQL Explanation:
# This creates a view named 'v_users' that:
# - Selects data from the 'users' table
# - Returns JSONB objects with fields: id, name, email
# - Uses jsonb_build_object for efficient JSON construction
#
# Potential Issues:
# - Consider adding an index on frequently filtered columns
# - Missing WHERE clause may return soft-deleted records
Workflow Examples¶
Complete Project Setup¶
# 1. Create project
fraiseql init blog-api --template blog
cd blog-api
# 2. Set up Python environment
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# 3. Generate database migrations
fraiseql generate migration User
fraiseql generate migration Post
fraiseql generate migration Comment
# 4. Apply migrations
psql $DATABASE_URL -f migrations/*_create_users.sql
psql $DATABASE_URL -f migrations/*_create_posts.sql
psql $DATABASE_URL -f migrations/*_create_comments.sql
# 5. Generate CRUD operations
fraiseql generate crud User
fraiseql generate crud Post
fraiseql generate crud Comment
# 6. Validate project
fraiseql check
# 7. Start development server
fraiseql dev
Pre-Deployment Checklist¶
# Validate project structure and types
fraiseql check
# Generate latest schema for frontend
fraiseql generate schema -o frontend/schema.graphql
# Validate all custom SQL views
for sql in migrations/*.sql; do
fraiseql sql validate "$sql"
done
# Run tests
pytest
# Deploy
docker build -t my-api .
docker push my-api
Database Development Workflow¶
# 1. Generate view from Python type
fraiseql sql generate-view User --module src.types -o views/user.sql
# 2. Validate the generated SQL
fraiseql sql validate views/user.sql
# 3. Explain the SQL for review
fraiseql sql explain views/user.sql
# 4. Apply to database
psql $DATABASE_URL -f views/user.sql
Environment Variables¶
FraiseQL CLI respects these environment variables:
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
- | PostgreSQL connection string |
FRAISEQL_DATABASE_URL |
- | Alternative database URL |
FRAISEQL_AUTO_CAMEL_CASE |
false |
Auto-convert snake_case to camelCase |
FRAISEQL_DEV_AUTH_PASSWORD |
- | Development auth password |
FRAISEQL_ENVIRONMENT |
development |
Environment (development/production) |
Exit Codes¶
| Code | Meaning |
|---|---|
0 |
Success |
1 |
General error (check stderr output) |
2 |
Invalid command or missing arguments |
Troubleshooting¶
Command Not Found¶
# Ensure fraiseql is installed
pip install fraiseql
# Check installation
which fraiseql
fraiseql --version
Not in Project Directory¶
Most commands require you to be in a FraiseQL project directory:
# Check for pyproject.toml
ls pyproject.toml
# Or initialize new project
fraiseql init my-project
cd my-project
Import Errors¶
# Install development dependencies
pip install -e ".[dev]"
# Ensure virtual environment is activated
source .venv/bin/activate # Linux/Mac
.venv\Scripts\activate # Windows
Database Connection Issues¶
# Set DATABASE_URL environment variable
export DATABASE_URL="postgresql://user:pass@localhost/dbname"
# Or add to .env file
echo "FRAISEQL_DATABASE_URL=postgresql://localhost/mydb" >> .env
Tips and Best Practices¶
-
Always validate before deploying: Use
fraiseql checkin CI/CD pipelines -
Generate schema for frontend teams: Keep
schema.graphqlin version control -
Use migrations for database changes: Generate migrations with timestamps for proper ordering
-
Validate custom SQL: Always run
fraiseql sql validateon hand-written views -
Development workflow: Use
fraiseql devwith auto-reload for fast iteration -
Script common tasks:
See Also¶
- 5-Minute Quickstart - Get started quickly
- Database API - Repository patterns
- Production Deployment - Deployment guide
- Configuration - Application configuration
Need help? Run any command with --help for detailed usage information: