【问题标题】:Sequelize ORM can't use sync()Sequelize ORM 不能使用 sync()
【发布时间】:2020-01-16 04:07:42
【问题描述】:

这是一个文件的摘录,该文件使用 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 路线顺便在另一个名为 tasks.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

谢谢,

【问题讨论】:

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


    【解决方案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 并与index.js 一起放入models 文件夹中

    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 以来一直在使用的(当时只有 v2 可用),并且当他们升级版本时我一直在“升级”index.js 文件,但这个是ev4 和新的 v5 完全相同...

    试一试,我相信它会对您的 Sequielize 项目有所帮助...

    在我的一个新项目中:

    【讨论】:

    • 这是一个关于如何布置项目的清晰而伟大的解释,非常感谢
    【解决方案2】:

    这是正确的行为,你导出 sequelize 实例和 Sequelize 类,所以你应该使用db.sequelize.sync()

    【讨论】:

      猜你喜欢
      • 2020-09-05
      • 2015-06-16
      • 2019-09-06
      • 2017-03-18
      • 2018-11-27
      • 1970-01-01
      • 1970-01-01
      • 2015-11-06
      • 2016-01-29
      相关资源
      最近更新 更多