开发者问题收集

NextJS 13 和 Mongoose 有时会抛出 OverwriteModelError

2023-08-06
161

我尝试将 NextJS 13.4.12 与 mongoose 7.4.2 一起使用 当我从 Web 浏览器获取 RestAPI 时,有时会出现 OverrideModelError。

我将项目上传到 github: https://github.com/pzoli/homework4nextjs

我的 Difficulty.ts 数据定义如下:

import mongoose, { Schema, model, Types } from "mongoose";

const difficultySchema = new Schema({
    name: {
        type: String,
        required: true,
    },
    value: {
        type: Number,
        required: true,
    },
});

export default mongoose.models.Difficulty || model("difficulty", difficultySchema);

我的 dbConnect.ts 是这样的:

import mongoose, { connect } from "mongoose";

let cached: undefined | Promise<void>;
export default () => {
  if (mongoose.connections && mongoose.connections[0].readyState)
    return Promise.resolve();

  if (!cached) {
    cached = connect(process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/quiz')
      .then(() => console.log("connected to database."))
      .catch((err) => console.log("could not connect to database", err));
  }
  return cached;
}

difficulty 目录中的 page.tsx 是:

"use client";

import React from 'react'
import { DataTable } from "primereact/datatable"
import { Column } from "primereact/column"
import { useQuery } from '@tanstack/react-query';
import Link from 'next/link';

export default function Difficulty() {

    const { data: difficultyValues, status: dataFetchStatus, isLoading: isDataLoading } = useQuery({
        queryKey: ["difficulty"],
        queryFn: async () => {
            const res = await fetch(`/api/difficulty`, { cache: "no-cache" });
            return res.json();
        }
    });

    return (
        <>
            <DataTable value={difficultyValues} loading={isDataLoading}>
                <Column field='name' header="Name"></Column>
            </DataTable>
            <Link href="/">Home</Link>
        </>
    )
}

route.ts 如下:

import Difficulty from "@/app/api/models/Difficulty";
import connection from "@/app/lib/dbConnect";
import { NextResponse } from "next/server";

export async function GET() {
    await connection();
    let result = await Difficulty.find({});
    return NextResponse.json(result);
}

我的UserAnswer.ts 代码如下(在错误消息中引用,但未使用任何 route.ts):

import mongoose, { Schema, model, Types } from "mongoose";

const userAnswerSchema = new Schema({
    question_answer_id: {
        type: Types.ObjectId,
        required: true,
        ref: 'questionanswer'
    },
    recorded_time: {
        type: Date,
        required: false,
    },
    user_id: {
        type: Types.ObjectId,
        required: true,
        ref: 'user'
    },
    thinkingtime: {
        type: Number,
        required: true,
    },
});

export default mongoose.models.UserAnswer || model("useranswer", userAnswerSchema);;

整个错误消息是:

  • [31merror[39m OverwriteModelError: Cannot overwrite useranswer model once compiled. at Mongoose.model (E:\work\integrity\Homeworks\homework4nextjs\node_modules\mongoose\lib\index.js:563:13) at eval (webpack-internal:///(rsc)/./app/api/models/UserAnswer.ts:28:184) at (rsc)/./app/api/models/UserAnswer.ts (E:\work\integrity\Homeworks\homework4nextjs.next\server\app\api\question\route.js:82:1) at webpack_require (E:\work\integrity\Homeworks\homework4nextjs.next\server\webpack-runtime.js:33:42) at eval (webpack-internal:///(rsc)/./app/api/models/QuestionAnswer.ts:7:69) at (rsc)/./app/api/models/QuestionAnswer.ts (E:\work\integrity\Homeworks\homework4nextjs.next\server\app\api\question\route.js:72:1) at webpack_require (E:\work\integrity\Homeworks\homework4nextjs.next\server\webpack-runtime.js:33:42) at eval (webpack-internal:///(rsc)/./app/api/models/Question.ts:7:73) at (rsc)/./app/api/models/Question.ts (E:\work\integrity\Homeworks\homework4nextjs.next\server\app\api\question\route.js:62:1) at webpack_require (E:\work\integrity\Homeworks\homework4nextjs.next\server\webpack-runtime.js:33:42) at eval (webpack-internal:///(rsc)/./app/api/question/route.ts:5:82) at (rsc)/./app/api/question/route.ts (E:\work\integrity\Homeworks\homework4nextjs.next\server\app\api\question\route.js:92:1) at webpack_require (E:\work\integrity\Homeworks\homework4nextjs.next\server\webpack-runtime.js:33:42) at eval (webpack-internal:///(rsc)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fquestion%2Froute&page=%2Fapi%2Fquestion%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fquestion%2Froute.ts&appDir=E%3A%5Cwork%5Cintegrity%5CHomeworks%5Chomework4nextjs%5Capp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=E%3A%5Cwork%5Cintegrity%5CHomeworks%5Chomework4nextjs&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!:16:126) at (rsc)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fquestion%2Froute&page=%2Fapi%2Fquestion%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fquestion%2Froute.ts&appDir=E%3A%5Cwork%5Cintegrity%5CHomeworks%5Chomework4nextjs%5Capp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=E%3A%5Cwork%5Cintegrity%5CHomeworks%5Chomework4nextjs&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D! (E:\work\integrity\Homeworks\homework4nextjs.next\server\app\api\question\route.js:42:1) at webpack_require (E:\work\integrity\Homeworks\homework4nextjs.next\server\webpack-runtime.js:33:42) at webpack_exec (E:\work\integrity\Homeworks\homework4nextjs.next\server\app\api\question\route.js:692:39) at E:\work\integrity\Homeworks\homework4nextjs.next\server\app\api\question\route.js:693:28 at Object. (E:\work\integrity\Homeworks\homework4nextjs.next\server\app\api\question\route.js:696:3) at Module._compile (e:\work\integrity\Homeworks\homework4nextjs\lib\internal\modules\cjs\loader.js:1255:14) at Module._extensions..js (e:\work\integrity\Homeworks\homework4nextjs\lib\internal\modules\cjs\loader.js:1309:10) at Module.load (e:\work\integrity\Homeworks\homework4nextjs\lib\internal\modules\cjs\loader.js:1113:32) at Module._load (e:\work\integrity\Homeworks\homework4nextjs\lib\internal\modules\cjs\loader.js:960:12) at Module.require (e:\work\integrity\Homeworks\homework4nextjs\lib\internal\modules\cjs\loader.js:1137:19) at require (e:\work\integrity\Homeworks\homework4nextjs\lib\internal\modules\helpers.js:121:18) at requirePage (e:\work\integrity\Homeworks\homework4nextjs\node_modules\next\dist\server\require.js:112:75) at e:\work\integrity\Homeworks\homework4nextjs\node_modules\next\dist\server\load-components.js:80:84 at process.processTicksAndRejections (e:\work\integrity\Homeworks\homework4nextjs\lib\internal\process\task_queues.js:95:5) at async loadComponentsImpl (e:\work\integrity\Homeworks\homework4nextjs\node_modules\next\dist\server\load-components.js:80:26) at async DevServer.findPageComponentsImpl (E:\work\integrity\Homeworks\homework4nextjs\node_modules\next\dist\server\next-server.js:434:36) {name: 'OverwriteModelError', digest: undefined, stack: 'OverwriteModelError: Cannot overwrite useran…dules\next\dist\server\next-server.js:434:36)', message: 'Cannot overwrite useranswer` model once compiled.', Symbol(NextjsError): 'server'}

我使用“npm run dev”命令运行项目。如果我使用“npm run build”和“npm run start”运行,则错误会按照我的测试消失。 错误不是第一次出现,有时需要刷新页面。请帮助找出我如何正确使用它。

1个回答

我测试了一个解决方案。只需将名称改为大写,就像您的模型名称一样:

export default mongoose.models.Difficulty || model("Difficulty", difficultySchema);

和驼峰式命名法:

export default mongoose.models.UserAnswer || model("UserAnswer", userAnswerSchema);

错误就消失了。

Papp Zoltán
2023-08-13