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

在Next.js中使用内存型SQLite:如何运行数据初始化函数?

解决Next.js中SQLite内存库初始化问题

针对你的需求——每次Next.js启动/热重载时初始化内存SQLite数据库,以下是两种可行方案:

方案一:模块加载时自动初始化

直接修改你的数据库模块(比如db.js),在文件末尾添加服务端专属的初始化逻辑,利用Node.js模块加载机制实现启动/重载时自动执行:

import { Sequelize, QueryTypes } from "sequelize";

const sequelize = new Sequelize("sqlite::memory:");

export const isConnOk = async () => {
  try {
    await sequelize.authenticate();
    console.log("Connection has been established successfully.");
  } catch (error) {
    console.error("Unable to connect to the database:", error);
  }
};

export const execute = async (sql) => {
  const [results, metadata] = await sequelize.query(sql);
  return [results, metadata];
};

export const query = async (sql) => {
  const results = await sequelize.query(sql, { type: QueryTypes.SELECT });
  return results;
};

export const populateUsers = async () => {
  try {
    console.log("START: populating database");

    await execute(
      "create table users ( id integer, name varchar(50), username varchar(50), city_of_birth varchar(50) );"
    );

    await execute(
      "insert into users values ( '1', 'gary', 'garym', 'seattle' );"
    );

    await execute(
      "insert into users values ( '2', 'christine', 'chris', 'miami' );"
    );

    console.log("COMPLETE: database populated");
  } catch {
    console.log("FAILURE: did not populate database");
  }
};

// 仅在服务端环境自动执行初始化
if (typeof window === 'undefined') {
  (async () => {
    try {
      await isConnOk();
      await populateUsers();
    } catch (err) {
      console.error('数据库初始化失败:', err);
    }
  })();
}

原理

  • typeof window === 'undefined'确保代码只在服务端运行,避免客户端报错
  • Next.js开发模式热重载时,服务端模块会被重新加载,因此每次重载都会执行初始化
  • 生产环境下模块仅加载一次,启动时执行初始化,完全匹配内存库的生命周期

方案二:主动调用初始化函数(更可控)

如果需要更精细地控制初始化时机,避免重复执行,可以添加初始化标志和确保初始化的函数:

1. 修改数据库模块

// ... 保留原有代码 ...

let isDbInitialized = false;

export const ensureDbReady = async () => {
  if (!isDbInitialized) {
    await isConnOk();
    await populateUsers();
    isDbInitialized = true;
    console.log('数据库已完成初始化');
  }
};

2. 在服务端代码中调用

  • Pages Router API路由:
// pages/api/users.js
import { ensureDbReady, query } from '../../db';

export default async function handler(req, res) {
  await ensureDbReady();
  const users = await query('SELECT * FROM users');
  res.status(200).json(users);
}
  • Pages Router 页面getServerSideProps:
// pages/users.js
import { ensureDbReady, query } from '../db';

export async function getServerSideProps() {
  await ensureDbReady();
  const users = await query('SELECT * FROM users');
  return { props: { users } };
}

export default function Users({ users }) {
  return <div>{JSON.stringify(users)}</div>;
}
  • App Router 服务端组件:
// app/users/page.js
import { ensureDbReady, query } from '../../db';

export default async function UsersPage() {
  await ensureDbReady();
  const users = await query('SELECT * FROM users');
  return <div>{JSON.stringify(users)}</div>;
}

原理

  • 通过isDbInitialized标志确保数据库仅初始化一次
  • 开发模式热重载时,模块重新加载会重置标志,因此会重新执行初始化
  • 所有数据库操作前先调用ensureDbReady(),保证数据可用

为什么_app.js的getServerSideProps不可行?

_app.js的getServerSideProps会在每个页面请求时执行,这会导致数据库被重复初始化,内存库中的数据会被反复清空,完全不符合演示需求。

内容的提问来源于stack exchange,提问作者Gary

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:35:23