Sequelize 抛出“TypeError:无法读取未定义的属性(读取‘构造函数’)”

问题描述 投票:0回答:1

我遇到了续集问题,无法理解问题到底来自哪里。我收到以下错误:

TypeError: Cannot read properties of undefined (reading 'constructor')
这是堆栈:

TypeError: Cannot read properties of undefined (reading 'constructor')\n" +
    '    at Function.findOne (/.../node_modules/sequelize/src/model.js:1977:61)\n' +
    '    at /.../src/api/controllers/execution.ts:22:31\n'

这是我在执行控制器中的内容:

let user = await User.findOne({ where: { id: req.body.externalCustomerId } });
if (!user) {
   throw new NotFoundError('No such user found');
}

我只是无法理解为什么续集会抛出此错误。我还有其他 2 个服务正在运行,这个调用没有问题。我在包含数据库的单独项目中有用户模型,并且那里有以下代码:

import argon2 from 'argon2';
import { Sequelize, Model, DataTypes, Op, QueryTypes } from 'sequelize';

export enum Role {
  admin = 'Admin',
  user = 'User',
  business = 'Business'
}

const validateEmailRegExp = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

export function validateEmailFormat(candidateEmail: string): boolean {
    return validateEmailRegExp.test(candidateEmail);
}

export function checkPasswordRequirements(candidatePassword: string): boolean {
    let valid = true;
  
    if (candidatePassword.length < 8) {
      valid = false;
    }
  
    // check if password contains a digit
    if (/\d/.test(candidatePassword) !== true) {
      valid = false;
    }
  
    // check if password contains a lowercase character
    if (/[a-z]/.test(candidatePassword) !== true) {
      valid = false;
    }
  
    // check if password contains an uppercase character
    if (/[A-Z]/.test(candidatePassword) !== true) {
      valid = false;
    }
  
    return valid;
}

class User extends Model {
  declare id: number;
  declare role: string;
  declare firstName: string;
  declare lastName: string;
  declare email: string;
  declare passcode: string;
  declare birthdate: string;
  declare country: string;
  declare phone: string;
  declare createdAt: string;
  declare active: boolean;

  static async initModel(sequelize: Sequelize) {
    console.log('Syncing user model...');
    this.init({
      id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
      },
      role: {
        type: DataTypes.ENUM(...Object.values(Role)),
        allowNull: false,
        defaultValue: Role.user,
        validate: {
          isIn: [ Object.values(Role) ]
        }
      },
      firstName: {
        type: DataTypes.STRING,
        allowNull: false
      },
      lastName: {
        type: DataTypes.STRING,
        allowNull: false
      },
      email: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true,
        validate: {
          isEmail: true
        }
      },
      passcode: {
        type: DataTypes.STRING,
        allowNull: false
      },
      birthdate: {
        type: DataTypes.STRING,
        allowNull: false
      },
      country: {
        type: DataTypes.STRING,
        allowNull: false
      },
      phone: {
        type: DataTypes.STRING,
        allowNull: false
      }
      active: {
        type: DataTypes.BOOLEAN,
        allowNull: false
      }
    }, {
      sequelize,
      indexes: [{ unique: true, fields: ['email'] }],
    }
    });

    User.beforeCreate(async (user, options) => {
      // always lowercase user email before saving
      user.email = user.email.toLowerCase();

      const hashedPassword = await argon2.hash(user.passcode as string);
      user.passcode = hashedPassword;
    });

    User.beforeUpdate(async (user, options) => {
      // hash user password if it was changed
      if (user.changed('passcode')) {
        const hashedPassword = await argon2.hash(user.passcode as string);
        user.passcode = hashedPassword;
      }
    });
  }
}

export default User;

此外,这就是我连接到数据库的方式:

import { Sequelize } from 'sequelize';

import User from '../models/user';

export let sequelize: Sequelize | null = null;

export async function connectToDb(
    dbName: string,
    dbUser: string,
    dbPass: string,
    dbOptions: any
  ): Promise<Sequelize | null> {
    
    try {
      if (sequelize !== null) {
        // return existing instance
        return sequelize;
      }
      
      console.log(`Connecting to database ${dbName} on host ${dbOptions.host}`);
      sequelize = new Sequelize(dbName, dbUser, dbPass, dbOptions);
  
      try {
        await sequelize.authenticate();
        console.log(`Successfully connected to databse, syncing models...`);
        await initDbModels(sequelize);
        console.log('All DB models initialised.');
      } catch (error) {
        console.error(`Error connecting to database ${dbName}`);
        console.error(error);
      }
  
      return sequelize;
    } catch (err) {
      console.error(`Could not connect to database ${dbName}`);
      console.error(err);
  
      return null;
    }
}

export async function initDbModels(sequelize: Sequelize) {
    await User.initModel(sequelize);
    ...

    await sequelize.sync();
}

最后,这是我的

app.ts

import cors from 'cors';
import path from 'path';
import dotenv from 'dotenv';
import express from 'express';

import router from './routes/router';
import { morgan } from "./middleware/morgan";

import { connectToDb } from '../modules/commons/tools/db-helper';
import { apiErrorHandler } from '../modules/commons/error-handling/error-handler';
import { dbName, dbUser, dbPass, dbOptions } from '../modules/commons/database/database';

require('ts-node/register');

dotenv.config({
  path: `.env.${process.env.NODE_ENV}`
});

var corsOptions: cors.CorsOptions = {
  origin: function (origin, callback) {
    callback(null, true)
  }
}

if (process.env.NODE_ENV !== 'production') {
  corsOptions.origin = '*';
}

var app = express();

const originalSend = app.response.send;
app.response.send = function sendOverride(body) {
  this.responseBody = body;
  return originalSend.call(this, body);
};

connectToDb(dbName, dbUser, dbPass, dbOptions);

app.use(cors(corsOptions));
app.use(morgan(':remote-addr [:date[clf]] ":method :url HTTP/:http-version" Input :input Response :status :response-body'));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ limit: '10mb', extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(router);
app.use(apiErrorHandler);
app.set('trust proxy', true);

export default app;
node.js typescript postgresql express sequelize.js
1个回答
0
投票

我发现了这个问题,而且非常明显,但我很困惑,因为其他 2 个服务运行良好。此外,我无法在日志中看到错误。

几天前,我创建了一个负责数据库连接的公共子模块,并在那里安装了

sequelize
包,但我忘记安装
pg
包了。另一方面,在数据库连接工作正常的 2 个服务中,我已经安装了
pg
软件包,这就是它们一直工作的原因。

所以,我刚刚在我的 commons 子模块中安装了

pg
,一切都工作正常。此外,我已经从服务中卸载了
pg
,因为它已经安装在子模块中。

© www.soinside.com 2019 - 2024. All rights reserved.