You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:从数据库表逆向重建remult.dev实体

从数据库表生成Remult.dev实体的解决方案

针对200张表的批量场景,推荐以下几种可行方案:

1. 自定义脚本批量生成Remult实体

直接写脚本读取数据库元数据(比如MySQL的information_schema.TABLES和information_schema.COLUMNS),按照Remult的实体规则自动生成TypeScript代码,这是最灵活的方案:

  • 步骤:
    • 用数据库驱动(如mysql2、pg)连接数据库,批量获取所有表的字段信息(字段名、类型、是否主键、是否可为空、默认值等)
    • 编写映射逻辑:把数据库字段类型转成Remult支持的TypeScript类型,同时生成@Entity和@Field装饰器配置
    • 遍历所有表,将生成的实体代码写入对应.ts文件
  • 示例代码片段(MySQL为例):
    import mysql from 'mysql2/promise';
    import fs from 'fs';
    import path from 'path';
    
    async function generateRemultEntities() {
      const connection = await mysql.createConnection({ 
        host: 'localhost',
        user: 'your_user',
        password: 'your_pwd',
        database: 'your_db'
      });
      // 获取所有表名
      const [tables] = await connection.execute('SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ?', ['your_db']);
      
      // 创建实体目录
      const entityDir = './remult-entities';
      if (!fs.existsSync(entityDir)) fs.mkdirSync(entityDir);
      
      for (const table of tables as any[]) {
        const tableName = table.TABLE_NAME;
        // 获取表字段信息
        const [columns] = await connection.execute(`
          SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT 
          FROM information_schema.COLUMNS 
          WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
        `, ['your_db', tableName]);
        
        // 生成实体代码
        let entityCode = `import { Entity, Field } from 'remult';\n\n`;
        entityCode += `@Entity('${tableName}')\n`;
        // 转成大驼峰类名
        const className = tableName.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
        entityCode += `export class ${className} {\n`;
        
        for (const col of columns as any[]) {
          const fieldOptions: string[] = [];
          if (col.COLUMN_KEY === 'PRI') {
            fieldOptions.push('primaryKey: true');
          }
          if (col.IS_NULLABLE === 'NO') {
            fieldOptions.push('nullable: false');
          }
          // 数据库类型到TS类型的映射
          let tsType = 'string';
          if (['int', 'bigint', 'tinyint', 'smallint'].includes(col.DATA_TYPE)) {
            tsType = 'number';
          } else if (['datetime', 'timestamp'].includes(col.DATA_TYPE)) {
            tsType = 'Date';
          } else if (col.DATA_TYPE === 'boolean') {
            tsType = 'boolean';
          }
          
          entityCode += `  @Field({ ${fieldOptions.join(', ')} })\n`;
          entityCode += `  ${col.COLUMN_NAME}: ${tsType};\n\n`;
        }
        entityCode += `}\n`;
        
        // 写入文件
        fs.writeFileSync(path.join(entityDir, `${className}.ts`), entityCode);
      }
      await connection.end();
      console.log('Remult实体生成完成');
    }
    generateRemultEntities();
    

2. 改造Typeorm/Prisma的生成结果

利用现有工具生成基础实体后,写脚本批量转换为Remult格式:

  • Typeorm:使用typeorm schema:generate生成实体后,写脚本替换装饰器(把@Entity()换成Remult的@Entity(),@Column()换成@Field(),同步主键、nullable等配置)
  • Prisma:先通过prisma db pull生成Prisma Schema,再写脚本解析Schema文件中的表和字段定义,批量生成对应的Remult实体类,还可以借助Prisma的postgenerate钩子自动触发转换脚本

3. 利用Remult的动态实体能力

如果不需要静态实体类(比如后台管理场景),可以基于Remult的EntityMetadata API,从数据库元数据动态注册实体:

// 示例:动态注册单个实体
await remult.context.em.registerEntity({
  name: 'your_table',
  fields: {
    id: {
      type: 'number',
      primaryKey: true
    },
    name: {
      type: 'string',
      nullable: false
    }
  }
});

不过静态实体类在开发时的类型提示更友好,建议优先选择静态生成方案。


内容的提问来源于stack exchange,提问作者Leonel Matias Domingos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:05:08