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
);

Optional Fields

Optional fields (T?) become nullable columns (no NOT NULL constraint).

Type Mapping

Paradox SQLite PostgreSQL

Integer

INTEGER

BIGINT

Text

TEXT

TEXT

Boolean

INTEGER

BOOLEAN

Double

REAL

DOUBLE PRECISION