为什么 Sequelize 迁移创建表但模型无法连接到数据库

我正在学习如何在 Nodejs 中使用 Sequelize ORM 并将数据保存在 Postgres 数据库中.

我的目标是将用户数据插入到 Users 表中.我已经使用迁移创建了表,它可以工作.但是,我无法保存用户数据.我关注了许多资源,例如 Tut 1 Tut 2 等等,还是一样的错误

C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_apidatabasemodelsindex.js:12如果(config.use_env_variable){^TypeError:无法读取未定义的属性use_env_variable"在对象.<匿名>(C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_apidatabasemodelsindex.js:12:12)在 Module._compile (internal/modules/cjs/loader.js:776:30)在 babelWatchLoader (C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_api
ode_modulesabel-watchunner.js:51:13)在 Object.require.extensions.(匿名函数) [as .js] (C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_api
ode_modulesabel-watchunner.js:62:7)在 Module.load (internal/modules/cjs/loader.js:653:32)在 tryModuleLoad (internal/modules/cjs/loader.js:593:12)在 Module.require (internal/modules/cjs/loader.js:690:17)在需要(内部/模块/cjs/helpers.js:25:18)在对象.<匿名>(C:UsersHPDesktopAndelaprojectTutorialseact-projectchat_app_apiserverserver.js:1:1)在 Module._compile (internal/modules/cjs/loader.js:776:30)在 babelWatchLoader (C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_api
ode_modulesabel-watchunner.js:51:13)在 Object.require.extensions.(匿名函数) [as .js] (C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_api
ode_modulesabel-watchunner.js:62:7)

config/config.js

require('dotenv').config();模块.exports = {发展: {use_env_variable: 'DATABASE_URL_DEV',方言:'postgres',},测试: {use_env_variable: 'DATABASE_URL_TEST',方言:'postgres',},生产: {use_env_variable: 'DATABASE_URL',方言:'postgres',ssl:是的,方言选项:{ssl:是的,},},};

迁移/20190927083519-create-user.js

'使用严格';模块.exports = {up: (queryInterface, Sequelize) =>{返回 queryInterface.createTable('Users', {ID: {允许空:假,主键:真,类型:Sequelize.UUID,默认值:Sequelize.UUIDV4,},全名: {类型:Sequelize.STRING},电子邮件: {类型:Sequelize.STRING},密码: {类型:Sequelize.STRING},用户名: {类型:Sequelize.STRING},电话:{类型:Sequelize.STRING},图片: {类型:Sequelize.STRING},创建时间:{允许空:假,类型:Sequelize.DATE},更新时间:{允许空:假,类型:Sequelize.DATE}});},下:(queryInterface,Sequelize)=>{return queryInterface.dropTable('Users');}};

models/index.js

'使用严格';常量 fs = 要求('fs');常量路径 = 要求('路径');const Sequelize = require('sequelize');const basename = path.basename(__filename);常量 env = process.env.NODE_ENV ||'发展';const config = require(__dirname + '/../config/config.js')[env];//为什么返回 Undefined ?常量 db = {};让续集;如果(config.use_env_variable){sequelize = new Sequelize(process.env[config.use_env_variable], config);} 别的 {sequelize = new Sequelize(config.database, config.username, config.password, config);}fs.readdirSync(__dirname).filter(文件=> {return (file.indexOf('.') !== 0) &&(文件!==基本名称)&&(file.slice(-3) === '.js');}).forEach(文件 => {const model = sequelize['import'](path.join(__dirname, file));db[model.name] = 模型;});Object.keys(db).forEach(modelName => {if (db[modelName].associate) {db[modelName].associate(db);}});db.sequelize = 续集;db.Sequelize = 续集;模块.出口=分贝;

模型/用户

'使用严格';module.exports = (sequelize, DataTypes) =>{const User = sequelize.define('User', {ID: {类型:DataTypes.UUID,默认值:DataTypes.UUIDV4,主键:真,},全名:DataTypes.STRING,电子邮件:DataTypes.STRING,密码:DataTypes.STRING,用户名:DataTypes.STRING,电话:DataTypes.STRING,图片:DataTypes.STRING}, {});User.associate = 功能(模型){//关联可以在这里定义};返回用户;};

app.js

从'express'导入快递;从'cors'导入cors;从摩根"导入摩根;从'body-parser'导入bodyParser;从庆祝"导入{错误};从'./Routes/index'导入路线;常量应用程序 = 快递();app.use(cors());app.use(morgan('combined'));app.use(bodyParser.urlencoded({extended: true }));app.use(bodyParser.json());app.use('/api', 路由);app.use(错误());app.use((req, res) => {const error = new Error('找不到路由');错误状态= 404;返回 res.status(error.status).json({状态:error.status,消息:error.message,});});//服务器错误app.use((error, req, res) => {常量状态 = 错误状态 ||500;返回 res.status(status).json({地位,消息:error.message ||'服务器错误',});});导出默认应用程序;

.env

DATABASE_URL_DEV=postgres://postgres:.@localhost:5432/db_devDATABASE_URL_TEST=postgres://postgres:.@localhost:5432/db_testDATABASE_URL=postgres://user:password@host:5432/db_remote

controllers/userControllers.js

从'bcrypt'导入bcrypt;从jsonwebtoken"导入 jwt;从dotenv"导入 dotenv;从'../../database/models'导入模型;从'../Helpers/upload.Image'导入uploadImage;dotenv.config();类用户控制器 {静态异步注册(req,res){常量 { 正文:输入 } = req;input.password = bcrypt.hashSync(input.password, 10);尝试 {const image = await uploadImage(req, res);常量 { secure_url: img } = 等待图像;输入.图像 = img;console.log('########################',models.User);//不明确的常量结果 = 等待模型.用户.创建(输入);console.log('########################之后的结果', 结果);//这里出错删除结果.dataValues.password;const token = jwt.sign(result.dataValues, process.env.SECRET_KEY, { expiresIn: '1W' });result.dataValues.token = 令牌;常量状态 = 201;返回 res.status(status).json({地位,message: '用户成功创建',数据:result.dataValues,});} 捕捉(错误){console.log('错误########################', 错误);让 { 消息 } = error.errors[0];常量状态 = 500;消息 = 消息 ||'服务器错误';返回 res.status(status).json({地位,信息,});}}}导出默认用户控制器;

<块引用>

我仍然不知道为什么在 models/index.js 我的 config 变量 返回 undefined.

require(__dirname + '/../config/config.js')//返回对象env//返回环境const config = require(__dirname + '/../config/config.js')[env];//返回未定义

我花了 3 天调试,但我无法解决错误.任何帮助,非常感谢指导.

谢谢

解决方案

Guyz,我找到了问题的答案,

在 models/index.js

我将 process.env.NODE_ENV 更改为 process.env.NODE_ENV.trim()

'使用严格';常量 fs = 要求('fs');常量路径 = 要求('路径');const Sequelize = require('sequelize');const basename = path.basename(__filename);//前常量 env = process.env.NODE_ENV ||'发展';//后常量 env = process.env.NODE_ENV.trim() ||'发展';//添加 .trim()const config = require(__dirname + '/../config/config.js')[env];常量 db = {};让续集;如果(config.use_env_variable){sequelize = new Sequelize(process.env[config.use_env_variable], config);} 别的 {sequelize = new Sequelize(config.database, config.username, config.password, config);}...db.sequelize = 续集;db.Sequelize = 续集;模块.出口=分贝;

<块引用>

更多细节

package.json

脚本":{"db:migrate:dev": "续集 db:migrate --env 开发","db:migrate:test": "续集 db:migrate --env test","db:migrate:production": "续集 db:migrate --env production","db:reset": "续集 db:migrate:undo","start": "SET NODE_ENV=production && babel-watch server/server.js","dev": "SET NODE_ENV=development && babel-watch server/server.js","test": "SET NODE_ENV=testing && babel-watch server/server.js"}

示例,假设我通过在终端中输入来启动服务器

npm run dev如果我这样做 console.log(process.env.NODE_ENV)//输出是带有空格的开发".因此,process.env.NODE_ENV === "development"//返回 false或者"开发" === "开发"//返回 false

Javascript Trim() 删除字符串两边的空格

您想要更多资源吗?请访问 w3c

I am learning how to use Sequelize ORM in Nodejs and save data in Postgres Database.

My goal is to insert user data into Users table. I have created the table using migration, and it works. However, I am not able to save users data. I 've followed many resources for example Tut 1 Tut 2, etc.. , I still get the same error

C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_apidatabasemodelsindex.js:12
if (config.use_env_variable) {
           ^
TypeError: Cannot read property 'use_env_variable' of undefined
    at Object.<anonymous> (C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_apidatabasemodelsindex.js:12:12)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at babelWatchLoader (C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_api
ode_modulesabel-watchunner.js:51:13)    
    at Object.require.extensions.(anonymous function) [as .js] (C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_api
ode_modulesabel-watchunner.js:62:7)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Module.require (internal/modules/cjs/loader.js:690:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (C:UsersHPDesktopAndelaprojectTutorialseact-projectchat_app_apiserverserver.js:1:1)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at babelWatchLoader (C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_api
ode_modulesabel-watchunner.js:51:13)    
    at Object.require.extensions.(anonymous function) [as .js] (C:UsersHPDesktoppathprojectTutorialseact-projectchat_app_api
ode_modulesabel-watchunner.js:62:7)

config/config.js

require('dotenv').config();

module.exports = {
  development: {
    use_env_variable: 'DATABASE_URL_DEV',
    dialect: 'postgres',
  },
  test: {
    use_env_variable: 'DATABASE_URL_TEST',
    dialect: 'postgres',
  },
  production: {
    use_env_variable: 'DATABASE_URL',
    dialect: 'postgres',
    ssl: true,
    dialectOptions: {
      ssl: true,
    },
  },
};

migrations/20190927083519-create-user.js

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        primaryKey: true,
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
      },
      fullname: {
        type: Sequelize.STRING
      },
      email: {
        type: Sequelize.STRING
      },
      password: {
        type: Sequelize.STRING
      },
      username: {
        type: Sequelize.STRING
      },
      telephone: {
        type: Sequelize.STRING
      },
      image: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Users');
  }
};

models/index.js

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.js')[env];        // why this return Undefined ?
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

fs
  .readdirSync(__dirname)
  .filter(file => {
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => {
    const model = sequelize['import'](path.join(__dirname, file));
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

models/users

'use strict';
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    id: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
    },
    fullname: DataTypes.STRING,
    email: DataTypes.STRING,
    password: DataTypes.STRING,
    username: DataTypes.STRING,
    telephone: DataTypes.STRING,
    image: DataTypes.STRING
  }, {});
  User.associate = function (models) {
    // associations can be defined here
  };
  return User;
};

app.js

import express from 'express';
import cors from 'cors';
import morgan from 'morgan';
import bodyParser from 'body-parser';
import { errors } from 'celebrate';

import routes from './Routes/index';

const app = express();

app.use(cors());
app.use(morgan('combined'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.use('/api', routes);

app.use(errors());


app.use((req, res) => {
  const error = new Error('Route not found');
  error.status = 404;
  return res.status(error.status).json({
    status: error.status,
    message: error.message,
  });
});

// Server Error
app.use((error, req, res) => {
  const status = error.status || 500;
  return res.status(status).json({
    status,
    message: error.message || 'Server error',
  });
});

export default app;

.env

DATABASE_URL_DEV=postgres://postgres:.@localhost:5432/db_dev
DATABASE_URL_TEST=postgres://postgres:.@localhost:5432/db_test
DATABASE_URL=postgres://user:password@host:5432/db_remote

controllers/userControllers.js

import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import dotenv from 'dotenv';

import models from '../../database/models';
import uploadImage from '../Helpers/upload.Image';

dotenv.config();

class UserController {
  static async signup(req, res) {
    const { body: input } = req;
    input.password = bcrypt.hashSync(input.password, 10);
    try {
      const image = await uploadImage(req, res);
      const { secure_url: img } = await image;

      input.image = img;
      console.log('result before ########################', models.User);         // Undefined
      const result = await models.User.create(input);
      console.log('result after ########################', result);                // Error here
      delete result.dataValues.password;

      const token = jwt.sign(result.dataValues, process.env.SECRET_KEY, { expiresIn: '1W' });
      result.dataValues.token = token;
      const status = 201;
      return res.status(status).json({
        status,
        message: 'User successfully created',
        data: result.dataValues,
      });
    } catch (error) {
      console.log('error########################', error);
      let { message } = error.errors[0];
      const status = 500;
      message = message || 'Server error';
      return res.status(status).json({
        status,
        message,
      });
    }
  }
}

export default UserController;

I still don't know why in models/index.js my config variable return undefined.

require(__dirname + '/../config/config.js')           // return object

env                                                   // return environment

const config = require(__dirname + '/../config/config.js')[env];                //return Undefined

I spent 3 days debugging but I can not solve the Error. any help, guidance is highly appreciated.

Thanks

解决方案

Guyz, I found an answer to my problem,

in models/index.js

I change process.env.NODE_ENV to process.env.NODE_ENV.trim()

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);

// Before
const env = process.env.NODE_ENV || 'development';

// After
const env = process.env.NODE_ENV.trim() || 'development';    // add .trim()

const config = require(__dirname + '/../config/config.js')[env];
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

...

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

Further Details

package.json

"scripts": {
    "db:migrate:dev": "sequelize db:migrate --env development",
    "db:migrate:test": "sequelize db:migrate --env test",
    "db:migrate:production": "sequelize db:migrate --env production",
    "db:reset": "sequelize db:migrate:undo",
    "start": "SET NODE_ENV=production && babel-watch server/server.js",
    "dev": "SET NODE_ENV=development && babel-watch server/server.js",
    "test": "SET NODE_ENV=testing && babel-watch server/server.js"
  }

Example, Let's say if I start the server by typing in the terminal

npm run dev 
If i do console.log(process.env.NODE_ENV)  // output is "development " with a space.

Hence, 
 process.env.NODE_ENV === "development"  // return false
 or
 "development " === "development" // return false

Javascript Trim() remove whitespace from both sides of a string

You want more resource? please visit w3c

相关文章