序列化ORM不能使用sync()

时间:2019-09-14 17:47:26

标签: node.js express orm synchronization sequelize.js

这是一个文件的摘录,该文件使用db作为db.js文件(连接到数据库的文件)中的变量。而且效果很好。

const Sequelize = require("sequelize")
const db = require("../database/db.js")

module.exports = db.sequelize.define(
  "physics_tbls", {
    id: {
      type: Sequelize.INTEGER,
      primaryKey: true,
      autoIncrement: true
    },...

当我在该文件的末尾添加db.sync()时,出现错误。这是上面文件的结尾,

.......
Sub_part: {
      type: Sequelize.STRING
    }
  }, {
    timestamps: false
  }
)

db.sync({
    // force: true
  })
  .then(() => {
    console.log('Connection to database established successfully.');
  })
  .catch(err => {
    console.log('Unable to connect to the database: ', err);
  })

我得到了错误,

TypeError: db.sync is not a function

如果db.sequelize有效,为什么db.sync()不起作用?

也许db.sync应该和包含变量db的db.js在同一个文件中。但是我确实需要先定义模型,然后才能进行sync()。

这是db.js

const Sequelize = require("sequelize")
const db = {}
const sequelize = new Sequelize("physics_papers_db", "root", "********", {
  host: "localhost",
  dialect: "mysql",
  // operatorsAliases: false,

  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
})

db.sequelize = sequelize
db.Sequelize = Sequelize


module.exports = db

我的Express路线偶然存在于另一个名为task.js的文件中

const Sequelize = require('sequelize')
var express = require("express")
var router = express.Router()
const Task = require("../model/Task")

//Test
router.get("/test", (req, res) => {
  Task.findAll({
      //Use attributes to only select specific fields
      attributes: ['Question', 'Marks']
    })
    .then(tasks => {
      console.log("router.get(\"/test\", (req, res) => {...");
      console.log("All tasks:", JSON.stringify(tasks, null, 4));
      res.json(tasks)
    })
    .catch(err => {
      res.send("error: " + err)
    })
})
........... more routes...

module.exports = router

谢谢

2 个答案:

答案 0 :(得分:1)

这是正确的行为,您导出sequelize实例和Sequelize类,因此应使用db.sequelize.sync()

答案 1 :(得分:1)

@ l2ysho的答案是正确的,但是我会做一些工作,以便您可以避免在代码中执行的“麻烦” ...使用ORM时,一般的想法是为我们提供帮助,而不仅仅是连接到数据库,或者不编写任何SQL,或者防止SQL注入,但是大多数情况下易于使用和更改...

请记住,在使用Sequelize时始终要这样做:

  • 在项目中创建一个models文件夹
  • 在该文件夹中添加一个index.js
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const _ = require('lodash');

const db = {};
const sequelize = new Sequelize(process.env.DB_DATABASE, process.env.DB_USER, process.env.DB_PWD, {
  host: process.env.DB_HOST,
  dialect: 'mysql',
  logging: process.env.APP_ENVIRONMENT !== 'local' ? null : console.log,
  pool: {
    max: 5,
    min: 0,
    idle: 10000,
  },
  operatorsAliases: false,
});

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

// add all associations
Object.keys(db).forEach(modelName => {
  if ('associate' in db[modelName]) {
    db[modelName].associate(db);
  }
});

module.exports = _.extend(
  {
    sequelize,
    Sequelize,
  },
  db
);

现在,为每个数据库模型添加一个文件,让我们假设您可能拥有一个logs表:

将其称为logs.js,并与models一起放入index.js文件夹

module.exports = (sequelize, DataTypes) => {
  const model = sequelize.define(
    'external_logs',
    {
      id: {
        type: DataTypes.INTEGER.UNSIGNED,
        primaryKey: true,
        autoIncrement: true,
        allowNull: false,
      },
      engine: { type: DataTypes.STRING, allowNull: false },
      response_code: { type: DataTypes.INTEGER.UNSIGNED, allowNull: true },
      origin: { type: DataTypes.STRING, allowNull: true },
      created_at: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: sequelize.literal('CURRENT_TIMESTAMP'),
      },
    },
    {
      timestamps: false,
      tableName: 'frontend_api_external_logs',
    }
  );

  model.associate = models => {
    model.belongsTo(models.campaigns, {
      foreignKey: 'campaign_id',
      allowNull: false,
      onDelete: 'cascade',
      onUpdate: 'cascade',
    });
    model.belongsTo(models.external_audit, {
      foreignKey: 'audit_id',
      allowNull: false,
      onDelete: 'cascade',
      onUpdate: 'cascade',
    });
  };

  return model;
};

如您所见,您可以非常轻松地轻松地与其他模型创建关联,而无需导入任何文件,然后可以根据您指定的定义调用此模型,在这种情况下:external_logs ...尽管已调用了真实的表名,但您可以看到:frontend_api_external_logs

如果最终需要调用任何模型或执行任何数据库任务,则只需调用该index.js文件,不仅数据库,而且所有具有自己关联的模型都可以作为好吧...例如,在一个utilities文件的database.js文件夹中,database.js可以简单地具有:

const db = require('./../models'); // same as './../models/index'

const logApiCall = (action, description) => {
   const logRow = {
       // content of the external logs table
       external_audit: {
           // content of the audit table as there's an association
       }
   }; // the content
   db.external_logs
      .create(logRow, { include: db.external_audit })
        // inserted
      })
      .catch(err => {
        // NOT inserted
        logger.log(`AUDIT ERROR: ${err.message}`);
        utilities.slack.sendMessage({ action, description, error: err.message });
      });
};

exports.logCall = logApiCall;

,这使得对用户执行的任何操作的审核日志更加容易执行,并且操作非常简单:

const db = require('./../utilities/database');

...

db.logCall('my action', 'my description');

如您所见,我不必担心我的文件是什么模型(不需要要求我正在使用的每个模型),只需调用一个可以处理所有文件的文件即可。

这是自从我开始使用Sequielize(只有第2版可用)以来我一直在使用的东西,并且在index.js文件颠簸版本时我一直在“升级”,但是这是一个与ev4和新的v5完全相同...

尝试一下,我相信它将帮助您完成Sequielize项目...

在我的一个新项目中: