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

在Express中配置Drizzle连接MySQL时遇变量未赋值错误

问题分析与解决

错误核心原因

你碰到的“Variable 'connection' is used before being assigned”错误,本质是立即执行异步函数(IIFE)的异步特性与变量赋值时机不匹配:

  • 你大概率先声明了let connection;,再通过(async () => { connection = await createConnection(...) })();完成赋值
  • 但IIFE是异步执行的,Express的路由或其他同步代码会在connection完成赋值前就尝试调用它,此时connection仍处于未赋值状态,触发报错

正确实现方案

方案1:启用顶级await(需调整项目配置)

如果想使用顶级await,先确保项目满足:

  • Node.js版本≥14.8.0
  • 将文件后缀改为.mjs,或在package.json中添加"type": "module"
  • 直接在顶层编写连接代码:
import { drizzle } from 'drizzle-orm/mysql2';
import mysql from 'mysql2/promise';

const connection = await mysql.createConnection({
  host: 'localhost',
  user: 'root',
  database: 'your_db'
});

export const db = drizzle(connection);

之后在Express路由中直接导入db即可——顶级await会阻塞模块加载,确保连接完成后才导出实例。

方案2:先初始化数据库再启动Express

若要保持CommonJS格式,可将连接逻辑封装成函数,在Express启动前完成初始化:

const { drizzle } = require('drizzle-orm/mysql2');
const mysql = require('mysql2/promise');
const express = require('express');
const app = express();

let db;

async function initDB() {
  const connection = await mysql.createConnection({
    host: 'localhost',
    user: 'root',
    database: 'your_db'
  });
  db = drizzle(connection);
}

// 先完成数据库初始化,再启动服务
initDB().then(() => {
  app.listen(3000, () => {
    console.log('Server running on port 3000');
  });
});

// 路由中使用时先判断连接状态
app.get('/data', async (req, res) => {
  if (!db) {
    return res.status(500).send('Database not initialized');
  }
  const data = await db.select().from(yourTable);
  res.json(data);
});

方案3:单例模式封装数据库连接

把连接逻辑封装成单例,确保每次获取的都是已初始化的实例:

const { drizzle } = require('drizzle-orm/mysql2');
const mysql = require('mysql2/promise');

class DB {
  static instance;

  static async getInstance() {
    if (!DB.instance) {
      const connection = await mysql.createConnection({
        host: 'localhost',
        user: 'root',
        database: 'your_db'
      });
      DB.instance = drizzle(connection);
    }
    return DB.instance;
  }
}

// 路由中调用
app.get('/data', async (req, res) => {
  const db = await DB.getInstance();
  const data = await db.select().from(yourTable);
  res.json(data);
});

避坑提示

  • 严禁在同步代码中直接引用异步赋值的变量,必须确保赋值完成后再使用
  • 不要用var声明connection,它仅提升变量声明、不提升赋值,同样会导致未定义问题
  • 生产环境更推荐使用连接池,只需把createConnection替换为createPool,逻辑保持一致

内容的提问来源于stack exchange,提问作者Aadi-23

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:17:04