Sequelize findAll 不是函数

Posted

技术标签:

【中文标题】Sequelize findAll 不是函数【英文标题】:Sequelize findAll is not a function 【发布时间】:2017-04-24 19:37:31 【问题描述】:

我正在使用 Sequelize 制作一个项目,但我被困在这一步。问题是,当我尝试登录并执行本地护照代码时,当它到达 User.findAll(...) 时,它会抛出 findAll 不是函数

如果我制作 console.log(User),它会显示 [function]。

我的结构:

/config/config.js /config/passport.js /models/index.js /models/nuke_users.js(由sequelize-auto生成) /index.js

config.js:

//Setting up the config
var Sequelize = require('sequelize');
var sequelize = new Sequelize('rocarenav2', 'root', '123456', 
   host: "localhost",
   port: 3306,
   dialect: 'mysql'
);

module.exports = sequelize;

passport.js:

// config/passport.js

// load all the things we need
var LocalStrategy   = require('passport-local').Strategy;

// load up the user model
var User            = require('../models/nuke_users');

var crypto          = require('crypto');

function hashPasswordForNuke(password) 
    return md5password =        crypto.createHash('md5').update(password).digest('hex');


// expose this function to our app using module.exports
module.exports = function(passport) 

// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session

// used to serialize the user for the session
passport.serializeUser(function(user, done) 
    done(null, user.id);
);

// used to deserialize the user
passport.deserializeUser(function(id, done) 
    User.findById(id, )
    .then(function (user) 
        done(err, user);
    )
    .catch(function (error)
        done(error);
    );
);



// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'

passport.use('local-login', new LocalStrategy(
    // by default, local strategy uses username and password, we will override with email
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true // allows us to pass back the entire request to the callback
,
function(req, email, password, done)  // callback with email and password from our form
    User.findAll(
        where: 
            'user_email': email
        
    ).then(function (user) 
        if(!user)
            return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash

        // if the user is found but the password is wrong
        if ((user.user_password).localeCompare(hashPasswordForNuke(password)) === -1)
            return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata

        return done(null, user);
    )
    .catch(function (error)
        done(error);
    );

));

;

模型/index.js

'use strict';

var fs        = require('fs');
var path      = require('path');
var Sequelize = require('sequelize');
var basename  = path.basename(module.filename);
var config    = require(__dirname + '/../config/config');
var db        = ;

//Create a Sequelize connection to the database using the URL in         config/config.js
var sequelize = config;

//Load all the models
fs
  .readdirSync(__dirname)
  .filter(function(file) 
      return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
 )
.forEach(function(file) 
    var model = sequelize['import'](path.join(__dirname, file));
    db[model.name] = model;
);

Object.keys(db).forEach(function(modelName) 
   if (db[modelName].associate) 
      db[modelName].associate(db);
   
);

//Export the db Object
db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

/models/nuke_users.js

/* jshint indent: 2 */

module.exports = function(sequelize, DataTypes) 
return sequelize.define('nuke_users', 
   user_id: 
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
   ,
   username: 
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: "",
      references: 
         model: 'reps_table',
         key: 'PostName'
      
   ,
   user_email: 
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: ""
   ,
   user_avatar: 
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: ""
   ,
   user_password: 
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: ""
   
 , 
    tableName: 'nuke_users'
 );
;

/index.js

...
var models = require('./models/');
...

那么,我做错了什么?

【问题讨论】:

在你的 passport.js 中尝试像 var models = require('../models'); var User = models.nuke_users; 好的,成功了。如何将您的答案标记为正确? 别担心。我太累了,写不出正确的答案。 【参考方案1】:

nuke_users 模块正在导出一个函数,该函数在调用时会返回 Model。因为你没有调用这个函数,所以它没有返回Model,因此你要找的函数不存在。

要调用此导出函数,您需要传入sequelize 实例和DataTypes,如下所示:

var User = require('../models/nuke_users')(sequelize, DataTypes);

在您的情况下,您在 index.js 文件中使用了一个加载器,它正在导出 db 对象,其中包含以它们的名称为键的模型。

var models = require('../models'); // loads index.js
var User = models.nuke_user;       // the model keyed by its name
User.findOne(...);                 // search the model

【讨论】:

【参考方案2】:

不要返回模型,而是从NukeUser.js导出它:

const NukeUser = sequelize.define('nuke_users', 
    // ...
);

module.exports = NukeUser;

然后在index.js:

const NukeUser = require('../models/NukeUser');
NukeUser.findAll() //.then() ...

【讨论】:

以上是关于Sequelize findAll 不是函数的主要内容,如果未能解决你的问题,请参考以下文章

sequelize/sequelize-typescript - 带有 HasMany 的 findAll 返回一个对象而不是数组

如何在 Sequelize Postgres 中使用小写函数

Sequelize js如何获取关联模型的平均值(聚合)

Sequelize findAll() with where-parameter 返回 null 而 findByPk() 返回正确的数据

使用 Sequelize 获取“TypeError:无法读取未定义的属性‘findAll’”

FindAll 包括更多关于 sequelize 查询的表