SQL vers MikroORM

Générateur d'Entités MikroORM TypeScript depuis SQL DDL

Convertissez les instructions SQL CREATE TABLE en classes d'entité MikroORM avec @Entity, @PrimaryKey, @Property, @Index et relations.

Préréglages :
Dialecte SQL:Nommage des Classes:Style des Propriétés:
Entrée SQL DDL (CREATE TABLE)
/**
 * MikroORM TypeScript Entities
 * Generated automatically by ToolsAA SQL to MikroORM Generator
 * Dialect: POSTGRES | Entities: 7
 */

import {
  Cascade,
  Collection,
  Entity,
  Enum,
  ManyToOne,
  OneToMany,
  OneToOne,
  PrimaryKey,
  Property,
  Unique,
} from '@mikro-orm/core';

// ============================================================================
// Database Enums
// ============================================================================

UserStatusEnum {
  ACTIVE = 'active',
  PENDING = 'pending',
  SUSPENDED = 'suspended',
  ARCHIVED = 'archived',
}

OrderStatusEnum {
  DRAFT = 'draft',
  PENDING = 'pending',
  PAID = 'paid',
  SHIPPED = 'shipped',
  CANCELLED = 'cancelled',
}

@Entity({ tableName: 'tenants' })
export class Tenant {
  @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
  id!: string;

  @Property({ unique: true, length: 64 })
  slug!: string;

  @Property({ length: 120, fieldName: 'company_name' })
  companyName!: string;

  @Property({ type: 'boolean', fieldName: 'is_active', default: true })
  isActive!: boolean;

  @Property({ onCreate: () => new Date() })
  createdAt: Date = new Date();

  @Property({ onUpdate: () => new Date() })
  updatedAt: Date = new Date();

  @OneToMany(() => User, (user) => user.tenant, { cascade: [Cascade.ALL], orphanRemoval: true })
  users = new Collection<User>(this);

  @OneToMany(() => Category, (category) => category.tenant, { cascade: [Cascade.ALL], orphanRemoval: true })
  categories = new Collection<Category>(this);

  @OneToMany(() => Product, (product) => product.tenant, { cascade: [Cascade.ALL], orphanRemoval: true })
  products = new Collection<Product>(this);

  @OneToMany(() => Order, (order) => order.tenant, { cascade: [Cascade.ALL], orphanRemoval: true })
  orders = new Collection<Order>(this);
}

@Entity({ tableName: 'users' })
@Unique({ properties: ['tenant', 'email'] })
export class User {
  @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
  id!: string;

  @Property({ length: 255 })
  email!: string;

  @Property({ length: 255, fieldName: 'password_hash' })
  passwordHash!: string;

  @Property({ length: 100, fieldName: 'display_name' })
  displayName!: string;

  @Enum(() => UserStatusEnum)
  status!: UserStatusEnum = UserStatusEnum.ACTIVE;

  @Property({ onCreate: () => new Date() })
  createdAt: Date = new Date();

  @Property({ onUpdate: () => new Date() })
  updatedAt: Date = new Date();

  @ManyToOne(() => Tenant, { fieldName: 'tenant_id', deleteRule: 'cascade' })
  tenant!: Tenant;

  @OneToOne(() => UserProfile, (userProfile) => userProfile.user)
  userProfile?: UserProfile;

  @OneToMany(() => Order, (order) => order.user, { cascade: [Cascade.ALL], orphanRemoval: true })
  orders = new Collection<Order>(this);
}

@Entity({ tableName: 'user_profiles' })
export class UserProfile {
  @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
  id!: string;

  @Property({ length: 500, nullable: true, fieldName: 'avatar_url' })
  avatarUrl?: string;

  @Property({ type: 'text', nullable: true })
  bio?: string;

  @Property({ length: 32, nullable: true, fieldName: 'phone_number' })
  phoneNumber?: string;

  @Property({ type: 'json', nullable: true })
  preferences?: Record<string, unknown>;

  @Property({ onCreate: () => new Date() })
  createdAt: Date = new Date();

  @OneToOne(() => User, { fieldName: 'user_id', deleteRule: 'cascade', owner: true })
  user!: User;
}

@Entity({ tableName: 'categories' })
@Unique({ properties: ['tenant', 'slug'] })
export class Category {
  @PrimaryKey({ autoincrement: true })
  id!: number;

  @Property({ length: 100 })
  name!: string;

  @Property({ length: 120 })
  slug!: string;

  @Property({ fieldName: 'sort_order', default: 0 })
  sortOrder!: number;

  @ManyToOne(() => Tenant, { fieldName: 'tenant_id', deleteRule: 'cascade' })
  tenant!: Tenant;

  @ManyToOne(() => Category, { fieldName: 'parent_id', deleteRule: 'set null', nullable: true })
  parent?: Category;

  @OneToMany(() => Category, (category) => category.parent, { cascade: [Cascade.ALL], orphanRemoval: true })
  children = new Collection<Category>(this);

  @OneToMany(() => Product, (product) => product.category, { cascade: [Cascade.ALL], orphanRemoval: true })
  products = new Collection<Product>(this);
}

@Entity({ tableName: 'products' })
@Unique({ properties: ['tenant', 'sku'] })
export class Product {
  @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
  id!: string;

  @Property({ length: 64 })
  sku!: string;

  @Property({ length: 200 })
  title!: string;

  @Property({ type: 'decimal', precision: 12, scale: 2 })
  price!: string;

  @Property({ fieldName: 'inventory_count', default: 0 })
  inventoryCount!: number;

  @Property({ type: 'json', nullable: true })
  attributes?: Record<string, unknown>;

  @Property({ type: 'array', nullable: true })
  tags?: string[];

  @Property({ type: 'boolean', fieldName: 'is_published', default: false })
  isPublished!: boolean;

  @Property({ onCreate: () => new Date() })
  createdAt: Date = new Date();

  @Property({ onUpdate: () => new Date() })
  updatedAt: Date = new Date();

  @ManyToOne(() => Tenant, { fieldName: 'tenant_id', deleteRule: 'cascade' })
  tenant!: Tenant;

  @ManyToOne(() => Category, { fieldName: 'category_id', deleteRule: 'set null', nullable: true })
  category?: Category;

  @OneToMany(() => OrderItem, (orderItem) => orderItem.product, { cascade: [Cascade.ALL], orphanRemoval: true })
  orderItems = new Collection<OrderItem>(this);
}

@Entity({ tableName: 'orders' })
export class Order {
  @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
  id!: string;

  @Property({ unique: true, length: 32, fieldName: 'order_number' })
  orderNumber!: string;

  @Enum(() => OrderStatusEnum)
  status!: OrderStatusEnum = OrderStatusEnum.DRAFT;

  @Property({ type: 'decimal', precision: 12, scale: 2 })
  subtotal!: string;

  @Property({ type: 'decimal', precision: 12, scale: 2, fieldName: 'tax_amount', default: 0.00 })
  taxAmount!: string;

  @Property({ type: 'decimal', precision: 12, scale: 2, fieldName: 'shipping_cost', default: 0.00 })
  shippingCost!: string;

  @Property({ type: 'decimal', precision: 12, scale: 2, fieldName: 'total_amount' })
  totalAmount!: string;

  @Property({ type: 'text', nullable: true })
  notes?: string;

  @Property({ onCreate: () => new Date() })
  createdAt: Date = new Date();

  @Property({ onUpdate: () => new Date() })
  updatedAt: Date = new Date();

  @ManyToOne(() => Tenant, { fieldName: 'tenant_id', deleteRule: 'cascade' })
  tenant!: Tenant;

  @ManyToOne(() => User, { fieldName: 'user_id', deleteRule: 'restrict' })
  user!: User;

  @OneToMany(() => OrderItem, (orderItem) => orderItem.order, { cascade: [Cascade.ALL], orphanRemoval: true })
  orderItems = new Collection<OrderItem>(this);
}

@Entity({ tableName: 'order_items' })
export class OrderItem {
  @PrimaryKey({ autoincrement: true })
  id!: string;

  @Property()
  quantity!: number;

  @Property({ type: 'decimal', precision: 12, scale: 2, fieldName: 'unit_price' })
  unitPrice!: string;

  @Property({ type: 'decimal', precision: 12, scale: 2, fieldName: 'line_total' })
  lineTotal!: string;

  @Property({ onCreate: () => new Date() })
  createdAt: Date = new Date();

  @ManyToOne(() => Order, { fieldName: 'order_id', deleteRule: 'cascade' })
  order!: Order;

  @ManyToOne(() => Product, { fieldName: 'product_id', deleteRule: 'restrict' })
  product!: Product;
}

Entités MikroORM7 entités générées
Relations Détectées10 clés étrangères résolues
Colonnes Converties58 colonnes typées

100% Confidentialité Côté Client

Aucun envoi serveur ni connexion externe. Le parsing SQL et la génération MikroORM se déroulent entièrement dans votre navigateur.

Décorateurs MikroORM v5 & v6 Complets

Mappage précis de @PrimaryKey (UUID, autoincrément), @Property, @Index, @Unique, @Enum et hooks automatiques onCreate/onUpdate.

Graphe Relationnel Typé & Multi-Dialectes

Détection des clés étrangères pour créer @ManyToOne, @OneToMany avec Collection<T> et @OneToOne sur PostgreSQL, MySQL, SQLite et MSSQL.

Référence technique et guide d'architecture

Guide du Développeur du Générateur d'Entités MikroORM TypeScript depuis SQL DDL — Guide de référence

Convertissez les instructions SQL CREATE TABLE en classes d'entité MikroORM avec @Entity, @PrimaryKey, @Property, @Index et relations.

Paramètres clés et contrôles

Dialecte SQL (SQL Dialect)Enum (PostgreSQL | MySQL | SQLite | MSSQL)

Spécifie la syntaxe SQL utilisée pour analyser les types de données, les séquences d'auto-incrémentation (SERIAL, AUTO_INCREMENT, IDENTITY) et les index.

Par défaut : PostgreSQL
Nommage des Classes (Class Naming Strategy)Enum (PascalCase Singulier | Conserver Nom de Table)

Contrôle la conversion des noms de tables SQL en noms de classes TypeScript, en transformant les tables au pluriel (ex. 'user_accounts') en identifiants PascalCase au singulier ('UserAccount').

Par défaut : PascalCase Singulier
Nommage des Propriétés (Property Naming Strategy)Enum (camelCase | Conserver snake_case)

Définit si les colonnes de la base de données sont converties en camelCase idiomatique avec @Property({ fieldName: 'nom_colonne' }) ou conservées au format snake_case d'origine.

Par défaut : camelCase
Génération des Relations (Relation Generation)Enum (Bidirectionnel (@ManyToOne & @OneToMany) | Clés Étrangères Scalaires Uniquement)

Configure si les contraintes de clés étrangères génèrent des relations MikroORM complètes avec Collection<T> ou de simples propriétés scalaires.

Par défaut : Bidirectionnel (@ManyToOne & @OneToMany)

Conseils de pro et bonnes practices

Dans MikroORM

Dans MikroORM, les collections inverses de relations @OneToMany ou @ManyToMany doivent être initialisées avec 'new Collection<T>(this)'. Cela élimine les erreurs de référence indéfinie et permet le bon fonctionnement des méthodes comme .init() et .getItems().

Lors de la déclaration de relations

Lors de la déclaration de relations entre fichiers séparés avec @ManyToOne(() => Author) et @OneToMany(() => Book, b => b.author), utilisez toujours des fonctions fléchées pour désigner l'entité cible afin de prévenir les blocages d'import cyclique dans Node.js.

Lors de la conversion de colonnes

Lors de la conversion de colonnes snake_case en propriétés camelCase en TypeScript, spécifiez explicitement @Property({ fieldName: 'colonne_sql' }). Cela assure une compatibilité parfaite avec les bases en production sans migrations intempestives.

Pièges courants et dépannage

Erreur de compilation TypeScript : 'Property has no initializer and is not definitely assigned in constructor' (TS2564)

Lorsque l'option strictPropertyInitialization est activée, ajoutez l'assertion d'assignation certaine '!' aux propriétés de l'entité (ex. 'name!: string;'). MikroORM hydrate ces valeurs dynamiquement depuis la base via l'EntityManager.

Le type de @Property n'est pas détecté lors de l'émission de métadonnées avec emitDecoratorMetadata

Si TypeScript ne parvient pas à déduire un type complexe ou une union générique, déclarez explicitement l'option type dans le décorateur, telle que @Property({ type: 'text', nullable: true }) ou @Property({ type: 'json' }).

Foire aux questions (FAQ)

Comment les clés primaires SQL sont-elles converties en décorateurs MikroORM ?▼

Les colonnes définies avec PRIMARY KEY et AUTO_INCREMENT ou SERIAL deviennent @PrimaryKey({ autoincrement: true }). Les clés primaires UUID sont mappées en @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' }), et les clés composites reçoivent @PrimaryKey() sur chaque propriété constitutive.

Comment les clés étrangères SQL sont-elles traduites en décorateurs relationnels ?▼

Les contraintes SQL REFERENCES sont transformées en @ManyToOne(() => TargetEntity, { nullable: ... }). Lorsque le mode bidirectionnel est activé, l'entité cible reçoit en vis-à-vis un @OneToMany(() => CurrentEntity, c => c.target) avec new Collection<CurrentEntity>(this).

Le code généré est-il compatible avec MikroORM v5 et v6 ?▼

Oui. Le code respecte les meilleures pratiques actuelles de MikroORM, avec des imports propres depuis '@mikro-orm/core', l'utilisation de Collection<T> et des modèles de configuration prêts à l'emploi pour mikro-orm.config.ts.

Mes schémas SQL ou structures de tables sont-ils transmis à un serveur tiers ?▼

Non. L'analyse syntaxique du DDL et la génération de code TypeScript s'exécutent intégralement côté client dans votre navigateur web. Aucun script SQL ni schéma ne quitte votre machine.

Outils et utilitaires connexes

Tous les outils →
Guide Développeur : Générateur de Schémas Mongoose et Modèles TypeScript depuis JSONDéveloppement

Infère et génère des schémas MongoDB Mongoose, interfaces Document TypeScript, sous-documents imbriqués, horodatages et modèles exportables depuis du JSON.

Ouvrir l'outil→
Guide Développeur du Générateur de Schémas de Validation Yup depuis JSONDéveloppement

Transformez des exemples JSON en schémas de validation d'objets Yup typés avec yup.string(), yup.number(), yup.array() et règles requises.

Ouvrir l'outil→
Guide Développeur : Générateur de Schémas de Validation Joi depuis JSONDéveloppement

Convertissez des structures de données JSON en schémas de validation Joi robustes avec les contraintes Joi.object(), Joi.string(), Joi.number() et Joi.array().

Ouvrir l'outil→
Guide Développeur du Convertisseur JSON vers Schéma Apache Avro (.avsc)Développement

Convertissez des charges utiles JSON en schémas Apache Avro (.avsc) prêts pour la production, avec gestion des espaces de noms, types primitifs et logiques, champs union avec null et règles d'évolution.

Ouvrir l'outil→
Guide Développeur : Générateur de Schémas de Validation Zod depuis GraphQL SDLDéveloppement

Convertissez les types, requêtes et inputs GraphQL SDL en schémas de validation Zod à l'exécution (z.object, z.string, z.array) avec prise en charge avancée de la nullabilité.

Ouvrir l'outil→
Guide de développement du convertisseur GraphQL SDL vers types et interfaces TypeScriptDéveloppement

Transformez vos types, inputs et énumérations GraphQL SDL directement en interfaces et types TypeScript propres et sans dépendances.

Ouvrir l'outil→