SQL Code Generation
paradox generate --sqlite [--path PATH]
paradox generate --postgresql [--path PATH]
Paradox generates DDL (Data Definition Language) for SQLite and PostgreSQL.
Product Types → Tables
Input:
type User
name: Text
email: Text
age: Integer
SQLite output:
CREATE TABLE "User" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"name" TEXT NOT NULL,
"email" TEXT NOT NULL,
"age" INTEGER NOT NULL
);
Every table gets an auto-incrementing id primary key.
Foreign Keys
Product fields that reference other product types become foreign keys:
type Post
author: User
title: Text
content: Text
published: Boolean
CREATE TABLE "Post" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"author" INTEGER NOT NULL,
"title" TEXT NOT NULL,
"content" TEXT NOT NULL,
"published" INTEGER NOT NULL,
FOREIGN KEY("author") REFERENCES "User"("id")
);
Typed Foreign Keys
Key wrap types generate explicit foreign key references:
wrap Key a: Integer
type Comment
postId: Key Post
userId: Key User
body: Text
CREATE TABLE "Comment" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"postId" INTEGER NOT NULL,
"userId" INTEGER NOT NULL,
"body" TEXT NOT NULL,
FOREIGN KEY("postId") REFERENCES "Post"("id"),
FOREIGN KEY("userId") REFERENCES "User"("id")
);
Validation → CHECK Constraints
Wrap type validations become inline CHECK constraints:
wrap Age: Integer
valid Age
unwrap >= 0
unwrap <= 150
type Profile
user: User
age: Age
bio: Text?
CREATE TABLE "Profile" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"user" INTEGER NOT NULL,
"age" INTEGER NOT NULL,
"bio" TEXT,
FOREIGN KEY("user") REFERENCES "User"("id"),
CONSTRAINT "Profile_age_check" CHECK (age >= 0 AND age <= 150)
);
Union Types
Unions become tables with a _tag discriminator column:
CREATE TABLE "PaymentStatus" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"_tag" TEXT NOT NULL,
"pending" INTEGER,
"completed" INTEGER,
"failed" TEXT
);
Type Mapping
| Paradox | SQLite | PostgreSQL |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|