SQL → Sequelize TS
Generación de código de base de datos y ORM

Generador de Modelos Sequelize TypeScript desde SQL DDL

Referencia técnica para desarrolladores sobre la conversión de DDL SQL CREATE TABLE en modelos tipados Sequelize TypeScript, definiciones DataTypes, atributos CreationOptional y declaraciones Model.init.

Privacidad 100% del lado del cliente
Cero transmisión al servidor
Preajustes:
Opciones del compilador SQL y mapeo de esquemas
postgres•Model.init
PostgreSQL5 tablas
Entrada DDL SQL CREATE TABLEPostgreSQL
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,
  };
}

Tablas y arquitectura detectadas (5)

usersUser
Columnas8
Clave primaria:id
Claves foráneas:0
user_profilesUserProfile
Columnas6
Clave primaria:id
Claves foráneas:1
productsProduct
Columnas8
Clave primaria:id
Claves foráneas:0
ordersOrder
Columnas7
Clave primaria:id
Claves foráneas:1
order_itemsOrderItem
Columnas5
Clave primaria:id
Claves foráneas:2

Privacidad Local Sin Cargas

Todo el análisis de DDL y la síntesis de código de modelos Sequelize se ejecutan al 100% en el entorno seguro de su navegador. Sus esquemas nunca salen de su equipo.

Doble Arquitectura TypeScript

Genere declaraciones estándar Model.init de Sequelize v6/v7 con interfaces completas o modernos decoradores de clase sequelize-typescript con comprobación estricta de tipos.

Relaciones y Migraciones Completas

Detecta automáticamente relaciones de clave externa 1:1, 1:N y N:M para generar declaraciones hasMany, belongsTo y scripts de migración para Sequelize CLI.

Referencia técnica y guía de arquitectura

Guía de Desarrollo: Generador de Modelos Sequelize TypeScript desde SQL DDL — Guía de referencia

Referencia técnica para desarrolladores sobre la conversión de DDL SQL CREATE TABLE en modelos tipados Sequelize TypeScript, definiciones DataTypes, atributos CreationOptional y declaraciones Model.init.

Parámetros clave y controles

ddlInputstring

Sentencias SQL CREATE TABLE que incluyen definiciones de columnas, claves primarias, nulabilidad, valores por defecto y restricciones de clave foránea.

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

Dialecto SQL de base de datos de destino que determina los DataTypes específicos de Sequelize (como JSONB, UUID, ENUM o INET).

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

Estilo de sintaxis TypeScript: Sequelize v6 InferAttributes/InferCreationAttributes, decoradores sequelize-typescript o interfaces tipadas clásicas.

Por defecto: v6-infer
camelCaseboolean

Convierte automáticamente nombres de columna snake_case en atributos camelCase de TypeScript con mapeo explícito de propiedad field.

Por defecto: true

Consejos profesionales y mejores prácticas

En Sequelize v6+

En Sequelize v6+, declare claves primarias autoincrementales, columnas con cláusula DEFAULT y marcas de tiempo con `declare id: CreationOptional<number>;`. Así, `Model.create()` no exigirá estos campos obligatoriamente, garantizando seguridad de tipos al consultar registros.

Active la opción camelCase para

Active la opción camelCase para trabajar en TypeScript con atributos limpios como createdAt o userId, mientras Sequelize gestiona la correspondencia con la base de datos mediante la opción `field: 'created_at'`.

Las sentencias SQL FOREIGN KEY generan

Las sentencias SQL FOREIGN KEY generan automáticamente atributos de clave foránea en Sequelize. Vincúlelas con las interfaces exportadas para estructurar asociaciones hasMany y belongsTo sin referencias circulares de tipos.

Errores comunes y solución de problemas

Error de TypeScript: La propiedad 'id' no tiene inicializador y no está asignada definitivamente en el constructor (TS2564)

Utilice la palabra clave `declare` para los atributos del modelo (por ejemplo, `declare id: CreationOptional<number>;`) en proyectos de TypeScript configurados con `useDefineForClassFields: true`.

Error de DataType no soportado al cambiar de dialecto (ej. DataTypes.JSONB en MySQL)

Seleccione el dialecto de base de datos correspondiente antes de procesar el DDL. El generador sustituirá automáticamente tipos exclusivos como JSONB o ARRAY por alternativas universales como `DataTypes.JSON` o `DataTypes.TEXT`.

Preguntas frecuentes (FAQ)

¿Cómo se traducen los tipos de datos SQL a Sequelize DataTypes?▼

Los tipos estándar de SQL (VARCHAR, INT, BIGINT, TIMESTAMP, BOOLEAN, TEXT, DECIMAL, JSON) se convierten con exactitud a sus homólogos de Sequelize (DataTypes.STRING, DataTypes.INTEGER, DataTypes.BIGINT, DataTypes.DATE, DataTypes.BOOLEAN, etc.). Los tipos propios de PostgreSQL como UUID o JSONB se conservan al seleccionar el dialecto correspondiente.

¿Es compatible con Sequelize v6 InferAttributes y con sequelize-typescript?▼

Sí. Permite generar código tanto con la sintaxis estándar de Sequelize v6 (`Model<InferAttributes<T>, InferCreationAttributes<T>>` y `Model.init`) como mediante decoradores para sequelize-typescript (`@Table`, `@Column`, `@PrimaryKey`, `@DataType`).

¿Cómo se transforman los valores DEFAULT y las restricciones NOT NULL?▼

Las columnas NOT NULL se configuran con `allowNull: false`. Las que poseen valor DEFAULT se transforman en `defaultValue: ...` y se tipan en TypeScript mediante `CreationOptional<T>` para permitir su omisión controlada en inserciones.

¿Se envía el esquema SQL o DDL a algún servidor externo?▼

No. Todo el análisis sintáctico de SQL, procesamiento léxico y generación de código TypeScript se ejecuta íntegramente en el navegador web del usuario a través de Web Workers locales. No se envía ni almacena información en servidores.

Herramientas y utilidades relacionadas

Todas las herramientas →