SQL DDL から MikroORM TypeScript エンティティ変換ジェネレーター

SQL DDL から MikroORM TypeScript エンティティ変換ジェネレーター

SQL CREATE TABLE 定義を解析し、@Entity、@PrimaryKey、@Property、@Index、およびリレーション装飾子を備えた MikroORM エンティティクラスに変換します。

プリセット:
SQL 方言:クラス命名規則:プロパティ命名:
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;
}

MikroORM エンティティ7 個のエンティティ生成
検出リレーション10 個の外部キー解決
変換カラム数58 個のカラム型付け

100% クライアントサイド安全処理

外部サーバー通信やDB接続は一切不要。すべてのSQL解析とMikroORMエンティティ変換がブラウザ内部で完結します。

MikroORM v5/v6 デコレーター完全対応

@PrimaryKey (UUID/自動採番/複合主キー)、@Property (型/長さ/NULL許容/defaultRaw)、@Index、@Unique、@Enum を高精度でマッピングします。

型安全なリレーション&複数DB方言対応

外部キー制約から @ManyToOne、@OneToMany Collection<T>、@OneToOne を自動構築。PostgreSQL、MySQL、SQLite、MSSQL に対応します。

技術リファレンス&アーキテクチャガイド

SQL DDL から MikroORM TypeScript エンティティ変換ジェネレーター — リファレンスガイド

SQL CREATE TABLE 定義を解析し、@Entity、@PrimaryKey、@Property、@Index、およびリレーション装飾子を備えた MikroORM エンティティクラスに変換します。

主要パラメータ&設定項目

SQL 方言 (SQL Dialect)Enum (PostgreSQL | MySQL | SQLite | MSSQL)

カラムのデータ型、シーケンスや自動採番(SERIAL、AUTO_INCREMENT、IDENTITY)、インデックス定義を正しく構文解析するための SQL データベース構文を指定します。

初期値: PostgreSQL
クラス命名規則 (Class Naming Strategy)Enum (PascalCase 単数形 | テーブル名を維持)

SQL テーブル名を TypeScript エンティティのクラス名へ変換するルールです。複数形テーブル名(例: 'user_accounts')を単数形の PascalCase(例: 'UserAccount')に自動変換します。

初期値: PascalCase 単数形
プロパティ命名規則 (Property Naming Strategy)Enum (camelCase | snake_case を維持)

データベースのカラム名を TypeScript のイディオムに沿った camelCase に変換し、@Property({ fieldName: 'column_name' }) で明示的マッピングを行うかを指定します。

初期値: camelCase
リレーション生成 (Relation Generation)Enum (双方向リレーション (@ManyToOne & @OneToMany) | 外部キーフィールドのみ)

外部キー制約から Collection<T> を含む双方向の MikroORM リレーション装飾子を生成するか、単一のスカラー外部キープロパティのみを出力するかを選択します。

初期値: 双方向リレーション (@ManyToOne & @OneToMany)

プロの活用テクニック&推奨設定

MikroORM

MikroORM では、@OneToMany や @ManyToMany の逆方向コレクションプロパティを 'new Collection<T>(this)' で初期化する必要があります。これにより未定義エラーを防ぎ、.init() や .getItems() などの遅延ロード操作が安定して動作します。

アロー関数によるエンティティ参照でモジュールの循環参照を防止する

@ManyToOne(() => Author) や @OneToMany(() => Book, book => book.author) のように、関連エンティティを ES6 アロー関数で遅延参照することで、ファイル分割時の Node.js モジュール循環インポート(評価順序デッドロック)を完全に回避できます。

明示的な fieldName 属性で既存データベースとの互換性を維持する

TypeScript 側で camelCase プロパティを採用する場合、@Property({ fieldName: 'db_col_name' }) を明示的に付与してください。これにより、既存スキーマを変更することなく、不要なマイグレーション差分の発生を防ぎます。

よくあるトラブルと解決策

TypeScript コンパイルエラー: 'プロパティに初期化子がなく、コンストラクターで割り当てられていません' (TS2564)

strictPropertyInitialization が有効な場合、MikroORM エンティティのプロパティに確実な代入アサーション '!' (例: 'name!: string;') を付与してください。値は MikroORM の Identity Map と EntityManager によってデータベースから動的に挿入されます。

TypeScript のリフレクションメタデータ出力時に @Property の型が正しく認識されない

emitDecoratorMetadata がジェネリクスや複雑な型を推論できない場合は、@Property({ type: 'text', nullable: true }) や @Property({ type: 'json' }) のように、デコレーターオプションで明示的に型を指定してください。

よくある質問 (FAQ)

SQL の主キー制約はどのように MikroORM デコレーターへ変換されますか?▼

PRIMARY KEY と AUTO_INCREMENT または SERIAL を持つ列は @PrimaryKey({ autoincrement: true }) に変換されます。UUID 主キーは @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' }) となり、複合主キーの場合は該当する各プロパティに @PrimaryKey() が付与されます。

外部キー制約(FOREIGN KEY)はどのように MikroORM のリレーションに変換されますか?▼

SQL の REFERENCES 制約は @ManyToOne(() => TargetEntity, { nullable: true/false }) に変換されます。双方向リレーションが有効な場合、参照先エンティティ側にも対となる @OneToMany(() => CurrentEntity, current => current.relationProp) と Collection<CurrentEntity>(this) が自動補完されます。

MikroORM v5 および v6 の新機能や構文仕様に対応していますか?▼

はい。最新の MikroORM 仕様に準拠しており、'@mikro-orm/core' からのクリーンなデコレーターインポート、Collection<T> 初期化、および mikro-orm.config.ts 設定ファイルのひな形出力をサポートしています。

入力した SQL スキーマや機密データが外部サーバーに送信されることはありますか?▼

いいえ。すべての SQL 構文解析および TypeScript エンティティ生成処理は、ブラウザ内のローカル JavaScript 環境で 100% 完結します。DDL 文やスキーマ情報が外部に送信されることは一切ありません。

関連するおすすめ開発ツール

すべてのツール →
JSONからMongooseスキーマ&TypeScriptモデル生成ツール開発ツール

JSONペイロードからMongoDB Mongooseスキーマ、TypeScript型定義(Document・DTO)、ネストされたサブドキュメント、タイムスタンプを推論・自動生成します。

ツールを開く→
JSON to Yup バリデーションスキーマ生成ツール開発ツール

JSONサンプルを型安全なYupオブジェクト検証スキーマに変換し、yup.string()、yup.number()、yup.array()、必須ルールを自動生成します。

ツールを開く→
JSON から Joi オブジェクト検証スキーマ自動生成ガイド開発ツール

サンプル JSON データ構造から Joi.object()、Joi.string()、Joi.number()、Joi.array() などの制約を備えた Joi バリデーションスキーマを瞬時に自動生成します。

ツールを開く→
JSON から Apache Avro スキーマ (.avsc) 変換ツール開発ツール

JSONペイロードから、名前空間、プリミティブ型、論理型、null許容共用体型、スキーマ進化ルールを備えた本番仕様のApache Avroスキーマ(.avsc)定義を生成します。

ツールを開く→
GraphQL SDL to Zod バリデーションスキーマ生成開発ツール

GraphQL SDL の型定義、クエリ、入力を、Null 許容性を適切に制御したランタイム Zod バリデーションスキーマ(z.object、z.string、z.array)へ自動変換します。

ツールを開く→
GraphQL SDL to TypeScript 型・インターフェース変換ツール開発ツール

GraphQL スキーマ定義言語 (SDL) の type、input、enum をクリーンで依存関係ゼロの TypeScript インターフェースや型エイリアスにブラウザ上で直接変換します。

ツールを開く→