SQL → Sequelize TS
Database & ORM Code Generation

SQL DDL to Sequelize TypeScript Model Generator

Convert SQL CREATE TABLE DDL into Sequelize TypeScript models, DataTypes definitions, attributes interfaces, and Model.init declarations.

100% Client-Side Privacy
Zero Server Transmission
Presets:
SQL Compiler Options & Schema Mapping
postgres•Model.init
PostgreSQL5 tables
SQL CREATE TABLE DDL InputPostgreSQL
import { DataTypes, Model, Optional, Sequelize } from 'sequelize';

// ============================================================================
// Sequelize TypeScript Models Generated by ToolsAA
// Dialect: POSTGRES | Syntax: Model.init
// ============================================================================

UserAttributes {
  id?: string;
  email: string;
  fullName?: string | null;
  role?: 'CUSTOMER' | 'ADMIN' | 'VENDOR';
  isActive?: boolean;
  metadata?: Record<string, any> | null;
  createdAt?: Date;
  updatedAt?: Date;
}

UserCreationAttributes extends Optional<UserAttributes, 'id' | 'fullName' | 'role' | 'isActive' | 'metadata' | 'createdAt' | 'updatedAt'> {}

export class User extends Model<UserAttributes, UserCreationAttributes> implements UserAttributes {
  public id!: string;
  public email!: string;
  public fullName!: string | null;
  public role!: 'CUSTOMER' | 'ADMIN' | 'VENDOR';
  public isActive!: boolean;
  public metadata!: Record<string, any> | null;
  public readonly createdAt!: Date;
  public readonly updatedAt!: Date;
}

initUser(sequelize: Sequelize): typeof User {
  User.init(
    {
      id: {
        type: DataTypes.UUID,
        primaryKey: true,
        allowNull: false,
        defaultValue: DataTypes.UUIDV4,
      },
      email: {
        type: DataTypes.STRING(255),
        allowNull: false,
        unique: true,
      },
      fullName: {
        type: DataTypes.STRING(120),
        allowNull: true,
        field: 'full_name',
      },
      role: {
        type: DataTypes.ENUM('CUSTOMER', 'ADMIN', 'VENDOR'),
        allowNull: false,
        defaultValue: 'CUSTOMER',
      },
      isActive: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: true,
        field: 'is_active',
      },
      metadata: {
        type: DataTypes.JSONB,
        allowNull: true,
      },
      createdAt: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
        field: 'created_at',
      },
      updatedAt: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
        field: 'updated_at',
      },
    },
    {
      sequelize,
      tableName: 'users',
      modelName: 'User',
      timestamps: true,
      underscored: true,
    }
  );
  return User;
}

UserProfileAttributes {
  id?: string;
  userId: string;
  avatarUrl?: string | null;
  phone?: string | null;
  shippingAddress?: string | null;
  taxIdentifier?: string | null;
}

UserProfileCreationAttributes extends Optional<UserProfileAttributes, 'id' | 'avatarUrl' | 'phone' | 'shippingAddress' | 'taxIdentifier'> {}

export class UserProfile extends Model<UserProfileAttributes, UserProfileCreationAttributes> implements UserProfileAttributes {
  public id!: string;
  public userId!: string;
  public avatarUrl!: string | null;
  public phone!: string | null;
  public shippingAddress!: string | null;
  public taxIdentifier!: string | null;

  // Association Mixin Placeholders
  // public getUser!: BelongsToGetAssociationMixin<User>;
}

initUserProfile(sequelize: Sequelize): typeof UserProfile {
  UserProfile.init(
    {
      id: {
        type: DataTypes.UUID,
        primaryKey: true,
        allowNull: false,
        defaultValue: DataTypes.UUIDV4,
      },
      userId: {
        type: DataTypes.UUID,
        allowNull: false,
        unique: true,
        field: 'user_id',
        references: {
          model: 'users',
          key: 'id',
        },
        onDelete: 'CASCADE',
      },
      avatarUrl: {
        type: DataTypes.STRING(500),
        allowNull: true,
        field: 'avatar_url',
      },
      phone: {
        type: DataTypes.STRING(30),
        allowNull: true,
      },
      shippingAddress: {
        type: DataTypes.TEXT,
        allowNull: true,
        field: 'shipping_address',
      },
      taxIdentifier: {
        type: DataTypes.STRING(50),
        allowNull: true,
        field: 'tax_identifier',
      },
    },
    {
      sequelize,
      tableName: 'user_profiles',
      modelName: 'UserProfile',
      timestamps: true,
      underscored: true,
    }
  );
  return UserProfile;
}

ProductAttributes {
  id?: number;
  sku: string;
  title: string;
  description?: string | null;
  price?: number;
  inventory?: number;
  isPublished?: boolean;
  createdAt?: Date;
}

ProductCreationAttributes extends Optional<ProductAttributes, 'id' | 'description' | 'price' | 'inventory' | 'isPublished' | 'createdAt'> {}

export class Product extends Model<ProductAttributes, ProductCreationAttributes> implements ProductAttributes {
  public id!: number;
  public sku!: string;
  public title!: string;
  public description!: string | null;
  public price!: number;
  public inventory!: number;
  public isPublished!: boolean;
  public readonly createdAt!: Date;
}

initProduct(sequelize: Sequelize): typeof Product {
  Product.init(
    {
      id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true,
        allowNull: false,
      },
      sku: {
        type: DataTypes.STRING(64),
        allowNull: false,
        unique: true,
      },
      title: {
        type: DataTypes.STRING(200),
        allowNull: false,
      },
      description: {
        type: DataTypes.TEXT,
        allowNull: true,
      },
      price: {
        type: DataTypes.DECIMAL(10, 2),
        allowNull: false,
        defaultValue: 0.00,
      },
      inventory: {
        type: DataTypes.INTEGER,
        allowNull: false,
        defaultValue: 0,
      },
      isPublished: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: true,
        field: 'is_published',
      },
      createdAt: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
        field: 'created_at',
      },
    },
    {
      sequelize,
      tableName: 'products',
      modelName: 'Product',
      timestamps: true,
      underscored: true,
      indexes: [
        {
          name: 'idx_products_sku',
          fields: ['sku'],
        },
      ],
    }
  );
  return Product;
}

OrderAttributes {
  id?: string;
  customerId: string;
  orderNumber: string;
  status?: 'PENDING' | 'PAID' | 'PROCESSING' | 'SHIPPED' | 'DELIVERED' | 'CANCELLED';
  totalAmount?: number;
  notes?: string | null;
  createdAt?: Date;
}

OrderCreationAttributes extends Optional<OrderAttributes, 'id' | 'status' | 'totalAmount' | 'notes' | 'createdAt'> {}

export class Order extends Model<OrderAttributes, OrderCreationAttributes> implements OrderAttributes {
  public id!: string;
  public customerId!: string;
  public orderNumber!: string;
  public status!: 'PENDING' | 'PAID' | 'PROCESSING' | 'SHIPPED' | 'DELIVERED' | 'CANCELLED';
  public totalAmount!: number;
  public notes!: string | null;
  public readonly createdAt!: Date;

  // Association Mixin Placeholders
  // public getUser!: BelongsToGetAssociationMixin<User>;
}

initOrder(sequelize: Sequelize): typeof Order {
  Order.init(
    {
      id: {
        type: DataTypes.UUID,
        primaryKey: true,
        allowNull: false,
        defaultValue: DataTypes.UUIDV4,
      },
      customerId: {
        type: DataTypes.UUID,
        allowNull: false,
        field: 'customer_id',
        references: {
          model: 'users',
          key: 'id',
        },
        onDelete: 'RESTRICT',
      },
      orderNumber: {
        type: DataTypes.STRING(64),
        allowNull: false,
        unique: true,
        field: 'order_number',
      },
      status: {
        type: DataTypes.ENUM('PENDING', 'PAID', 'PROCESSING', 'SHIPPED', 'DELIVERED', 'CANCELLED'),
        allowNull: false,
        defaultValue: 'PENDING',
      },
      totalAmount: {
        type: DataTypes.DECIMAL(12, 2),
        allowNull: false,
        defaultValue: 0.00,
        field: 'total_amount',
      },
      notes: {
        type: DataTypes.TEXT,
        allowNull: true,
      },
      createdAt: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
        field: 'created_at',
      },
    },
    {
      sequelize,
      tableName: 'orders',
      modelName: 'Order',
      timestamps: true,
      underscored: true,
      indexes: [
        {
          name: 'idx_orders_customer',
          fields: ['customer_id'],
        },
      ],
    }
  );
  return Order;
}

OrderItemAttributes {
  id?: number;
  orderId: string;
  productId: number;
  quantity?: number;
  unitPrice: number;
}

OrderItemCreationAttributes extends Optional<OrderItemAttributes, 'id' | 'quantity'> {}

export class OrderItem extends Model<OrderItemAttributes, OrderItemCreationAttributes> implements OrderItemAttributes {
  public id!: number;
  public orderId!: string;
  public productId!: number;
  public quantity!: number;
  public unitPrice!: number;

  // Association Mixin Placeholders
  // public getOrder!: BelongsToGetAssociationMixin<Order>;
  // public getProduct!: BelongsToGetAssociationMixin<Product>;
}

initOrderItem(sequelize: Sequelize): typeof OrderItem {
  OrderItem.init(
    {
      id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true,
        allowNull: false,
      },
      orderId: {
        type: DataTypes.UUID,
        allowNull: false,
        field: 'order_id',
        references: {
          model: 'orders',
          key: 'id',
        },
        onDelete: 'CASCADE',
      },
      productId: {
        type: DataTypes.INTEGER,
        allowNull: false,
        field: 'product_id',
        references: {
          model: 'products',
          key: 'id',
        },
        onDelete: 'RESTRICT',
      },
      quantity: {
        type: DataTypes.INTEGER,
        allowNull: false,
        defaultValue: 1,
      },
      unitPrice: {
        type: DataTypes.DECIMAL(10, 2),
        allowNull: false,
        field: 'unit_price',
      },
    },
    {
      sequelize,
      tableName: 'order_items',
      modelName: 'OrderItem',
      timestamps: true,
      underscored: true,
    }
  );
  return OrderItem;
}

// ============================================================================
// Unified Model Registry & Associations Initializer
// ============================================================================

DatabaseModels {
  User: typeof User;
  UserProfile: typeof UserProfile;
  Product: typeof Product;
  Order: typeof Order;
  OrderItem: typeof OrderItem;
}

initModels(sequelize: Sequelize): DatabaseModels {
  initUser(sequelize);
  initUserProfile(sequelize);
  initProduct(sequelize);
  initOrder(sequelize);
  initOrderItem(sequelize);

  // Setup Relationships
  UserProfile.belongsTo(User, { foreignKey: 'userId', as: 'user' });
  User.hasMany(UserProfile, { foreignKey: 'userId', as: 'userProfiles' });
  Order.belongsTo(User, { foreignKey: 'customerId', as: 'user' });
  User.hasMany(Order, { foreignKey: 'customerId', as: 'orders' });
  OrderItem.belongsTo(Order, { foreignKey: 'orderId', as: 'order' });
  Order.hasMany(OrderItem, { foreignKey: 'orderId', as: 'orderItems' });
  OrderItem.belongsTo(Product, { foreignKey: 'productId', as: 'product' });
  Product.hasMany(OrderItem, { foreignKey: 'productId', as: 'orderItems' });

  return {
    User,
    UserProfile,
    Product,
    Order,
    OrderItem,
  };
}

Detected Tables & Architecture (5)

usersUser
Columns8
Primary Key:id
Foreign Keys:0
user_profilesUserProfile
Columns6
Primary Key:id
Foreign Keys:1
productsProduct
Columns8
Primary Key:id
Foreign Keys:0
ordersOrder
Columns7
Primary Key:id
Foreign Keys:1
order_itemsOrderItem
Columns5
Primary Key:id
Foreign Keys:2

Zero-Upload Local Privacy

All SQL DDL parsing and Sequelize model code generation execute 100% locally in your browser sandbox. Your database architecture and proprietary schemas are never sent to any external server.

Dual TypeScript Architecture

Generate either standard Sequelize v6/v7 Model.init declarations with complete Attributes interfaces or modern sequelize-typescript class decorators with strong compile-time type safety.

Associations & Migrations Suite

Automatically detects 1:1, 1:N, and N:M foreign key relationships to generate hasMany, belongsTo, and belongsToMany declarations alongside Sequelize CLI migration scripts.

Technical Reference & Architecture Guide

SQL DDL to Sequelize TypeScript Model Generator — Reference Guide

Comprehensive developer reference for converting SQL CREATE TABLE DDL into typed Sequelize TypeScript models, DataTypes definitions, CreationOptional attributes, and Model.init declarations.

Key Parameters & Controls

ddlInputstring

Raw SQL CREATE TABLE statements including column definitions, primary keys, nullability, defaults, and foreign key constraints.

Default: CREATE TABLE users (...)
dialectenum ('postgres' | 'mysql' | 'sqlite' | 'mssql')

Target SQL database dialect that dictates dialect-specific Sequelize DataTypes such as JSONB, UUID, ENUM, or INET.

Default: postgres
tsSyntaxenum ('v6-infer' | 'decorators' | 'interface')

TypeScript model syntax style: Sequelize v6 InferAttributes/InferCreationAttributes, sequelize-typescript decorators, or classic typed interfaces.

Default: v6-infer
camelCaseboolean

Automatically convert snake_case SQL column names to camelCase TypeScript model attributes with explicit field mapping.

Default: true

Pro Tips & Best Practices

In modern Sequelize v6+

In modern Sequelize v6+, annotate auto-incrementing primary keys, columns with DEFAULT clauses, and timestamps with `declare id: CreationOptional<number>;`. This ensures `Model.create()` does not mandate these properties while keeping them non-optional on retrieved instances.

Enable camelCase conversion so your

Enable camelCase conversion so your TypeScript code works with idiomatic camelCase attributes (e.g., createdAt, userId), while Sequelize maps them to database column names via the `field: 'created_at'` property inside column definitions.

SQL `FOREIGN KEY

SQL `FOREIGN KEY (user_id) REFERENCES users(id)` declarations automatically generate Sequelize foreign key definitions. Pair them with exported model interfaces to build bidirectional hasMany and belongsTo associations without circular type conflicts.

Common Gotchas & Troubleshooting

TypeScript Error: Property 'id' has no initializer and is not definitely assigned in the constructor (TS2564)

Prefix model attributes with the `declare` keyword (e.g., `declare id: CreationOptional<number>;`) rather than standard property definitions when targeting TypeScript with `useDefineForClassFields: true`.

Unsupported DataType error when switching dialect (e.g., DataTypes.JSONB in MySQL)

Select the matching SQL dialect in generator options before parsing DDL. The generator will automatically substitute dialect-specific types like JSONB, ARRAY, or CITEXT with universal fallbacks such as `DataTypes.JSON` or `DataTypes.TEXT`.

Frequently Asked Questions

How does the generator handle SQL data types compared to Sequelize DataTypes?▼

The parser maps standard SQL types (VARCHAR, INT, BIGINT, TIMESTAMP, BOOLEAN, TEXT, DECIMAL, JSON) to their corresponding Sequelize DataTypes (DataTypes.STRING, DataTypes.INTEGER, DataTypes.BIGINT, DataTypes.DATE, DataTypes.BOOLEAN, DataTypes.TEXT, DataTypes.DECIMAL, DataTypes.JSON). Dialect-specific types like PostgreSQL UUID or JSONB are accurately preserved when the dialect is set.

Does the generator support both Sequelize v6 InferAttributes and sequelize-typescript?▼

Yes. You can switch between Sequelize v6 standard syntax (utilizing `Model<InferAttributes<T>, InferCreationAttributes<T>>` with `Model.init`) and decorator-based syntax compatible with sequelize-typescript (`@Table`, `@Column`, `@PrimaryKey`, `@DataType`).

How are DEFAULT values and NOT NULL constraints translated?▼

Columns defined with `NOT NULL` map to `allowNull: false`. Columns with `DEFAULT` values map to `defaultValue: ...` and are typed with `CreationOptional<T>`, allowing omission during `Model.create()` calls while guaranteeing type safety.

Is my database schema or SQL DDL sent to a remote server?▼

No. All SQL parsing, tokenization, and TypeScript code generation executes entirely client-side inside your browser via local Web Workers. No database schema or queries are uploaded or logged.

Related Tools & Utilities

All Tools →