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

Why Sequelize migration create table but models can not connect to a database

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

我的目标是将用户数据插入 Users table。我使用迁移创建了 table,它可以工作。但是,我无法保存用户数据。我已经关注了很多资源,例如 Tut 1 Tut 2,等等。,我仍然得到同样的错误

C:\Users\HP\Desktop\path\project\Tutorials\react-project\chat_app_api\database\models\index.js:12
if (config.use_env_variable) {
           ^
TypeError: Cannot read property 'use_env_variable' of undefined
    at Object.<anonymous> (C:\Users\HP\Desktop\path\project\Tutorials\react-project\chat_app_api\database\models\index.js:12:12)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at babelWatchLoader (C:\Users\HP\Desktop\path\project\Tutorials\react-project\chat_app_api\node_modules\babel-watch\runner.js:51:13)    
    at Object.require.extensions.(anonymous function) [as .js] (C:\Users\HP\Desktop\path\project\Tutorials\react-project\chat_app_api\node_modules\babel-watch\runner.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:\Users\HP\Desktop\Andela\project\Tutorials\react-project\chat_app_api\server\server.js:1:1)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at babelWatchLoader (C:\Users\HP\Desktop\path\project\Tutorials\react-project\chat_app_api\node_modules\babel-watch\runner.js:51:13)    
    at Object.require.extensions.(anonymous function) [as .js] (C:\Users\HP\Desktop\path\project\Tutorials\react-project\chat_app_api\node_modules\babel-watch\runner.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

我调试了3天,还是无法解决错误。非常感谢任何帮助和指导。

谢谢

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

models/index.js

我把process.env.NODE_ENV改成了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"
  }

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

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() 去除字符串两边的空格

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