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

Node.js项目中kysely-codegen生成SQL Server 2012类型失败+Kysely SQL编译异常求助

Node.js项目中kysely-codegen生成SQL Server 2012类型失败+Kysely SQL编译异常求助

我来帮你梳理下这两个问题的排查方向和可能的解决办法,你可以一步步尝试:


一、kysely-codegen生成类型时的UnhandledPromiseRejection错误

你遇到的UnhandledPromiseRejection: [object Array]错误,本质是kysely-codegen在 introspect 数据库时抛出了数组形式的错误,但没有被捕获。因为错误信息被隐藏成了[object Array],我们需要先拿到具体错误内容,再针对性解决。

可能的原因及排查步骤:

  1. 连接字符串的实例名称不一致
    你在kysely-codegen配置里用的是Server=localhost,1433,但在项目代码里用的是localhost\\SQLEXPRESS——如果你的SQL Server是默认的SQLEXPRESS实例,直接指定端口1433可能找不到实例(除非你手动修改过实例的端口配置)。

    • 解决:修改./.kysely-codegenrc.json里的连接字符串,把Server改成和代码一致的写法:
      "url": "Server=localhost\\SQLEXPRESS;Database=MedicalWEB;User Id=root;Password=root;Encrypt=false;TrustServerCertificate=true;"
      
    • 改完后重新执行npx kysely-codegen --config-file ./.kysely-codegenrc.json试试。
  2. 手动捕获具体错误内容
    直接用npx命令看不到具体的错误数组,我们可以写一个简单的脚本调用kysely的introspect功能,手动捕获错误:

    • 创建introspect-test.js文件:
      const { MssqlDialect } = require('kysely/dialects/mssql');
      const { ConnectionPool } = require('mssql');
      
      async function testIntrospection() {
        try {
          const dialect = new MssqlDialect({
            tarn: { options: { min: 0, max: 10 } },
            tedious: {
              connectionFactory: () => new ConnectionPool({
                authentication: {
                  type: 'default',
                  options: { userName: 'root', password: 'root' }
                },
                server: 'localhost\\SQLEXPRESS',
                database: 'MedicalWEB',
                port: 1433,
                encrypt: false,
                trustServerCertificate: true
              })
            }
          });
      
          const introspector = dialect.createIntrospector();
          const metadata = await introspector.getIntrospectionMetadata();
          console.log('Introspection success! Metadata preview:', {
            tables: metadata.tables.map(t => t.name)
          });
        } catch (err) {
          console.error('Introspection failed with detailed error:', err);
        }
      }
      
      testIntrospection();
      
    • 执行node introspect-test.js,就能看到具体的错误信息(比如是系统表权限不足,还是SQL Server版本兼容问题)。
  3. SQL Server 2012的兼容性问题
    SQL Server 2012是比较老旧的版本(2012年发布,已经停止主流支持),kysely-codegen的mssql dialect可能依赖了SQL Server 2016+的系统视图或语法。

    • 如果手动脚本的错误是系统视图不存在或语法不支持,你可以尝试:
      • (如果可行)升级SQL Server到2016或以上版本;
      • 查看kysely-codegen的GitHub issues,有没有其他用户遇到过SQL Server 2012的兼容问题,是否有临时补丁或配置项可以调整。
  4. 数据库权限不足
    Introspect需要读取SQL Server的系统表(比如sys.tables、sys.columns、sys.schemas等),如果你的用户没有权限访问这些对象,会导致 introspect 失败。

    • 给用户授予VIEW DEFINITION权限:
      USE MedicalWEB;
      GRANT VIEW DEFINITION ON DATABASE::MedicalWEB TO root;
      

二、Kysely默认用PostgreSQL编译SQL的异常

你提到Kysely会把SQL编译成PostgreSQL风格,这说明Kysely没有正确加载MssqlDialect,或者在代码中有配置错误。

排查步骤:

  1. 确认依赖安装完整
    Kysely的mssql dialect依赖tedious和mssql包,确保你已经安装了所有必要依赖:

    npm install kysely tedious mssql
    
  2. 检查Dialect的导入和实例化是否正确
    确保你没有误导入PostgresDialect,并且正确创建MssqlDialect实例:

    // 正确导入路径
    const { Kysely } = require('kysely');
    const { MssqlDialect } = require('kysely/dialects/mssql'); // 注意是kysely/dialects/mssql
    const { ConnectionPool } = require('mssql');
    
    async function initDb() {
      try {
        const dialect = new MssqlDialect({
          tarn: { options: { min: 0, max: 10 } },
          tedious: {
            connectionFactory: () => new ConnectionPool({
              authentication: {
                type: 'default',
                options: {
                  userName: process.env.DB_USER,
                  password: process.env.DB_PWD
                }
              },
              server: 'localhost\\SQLEXPRESS',
              database: process.env.DB_NAME,
              port: 1433,
              encrypt: false,
              trustServerCertificate: true
            })
          }
        });
    
        const db = new Kysely({ dialect });
    
        // 测试:执行一个简单的查询,看生成的SQL是否是MSSQL风格
        const testResult = await db
          .selectFrom('your_table_name')
          .select(['column1', 'column2'])
          .limit(1) // MSSQL会自动转换成TOP 1
          .execute();
    
        console.log('Test query executed successfully:', testResult);
        return db;
      } catch (err) {
        console.error('DB init failed:', err);
        throw err;
      }
    }
    

    注意:Kysely的MssqlDialect会自动把limit(1)转换成MSSQL的TOP 1语法,如果生成的SQL还是PostgreSQL的LIMIT 1,说明Dialect没有正确加载。

  3. 检查是否有代码覆盖DB实例
    确认项目中没有其他地方重新定义了db变量,或者使用了中间件/插件强制切换了Dialect。


内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 09:22:59