节点、Sequelize、同步模型、混合力:真/假

Posted

技术标签:

【中文标题】节点、Sequelize、同步模型、混合力:真/假【英文标题】:Node, Sequelize, Sync models, mixing force: true/false 【发布时间】:2019-09-13 12:21:39 【问题描述】:

我(再次)感到困惑。

在使用 Sequelize 定义数据库 (mysql) 表时,我想做一个 同步(强制:真),删除/创建表。到目前为止,一切都很好。

现在我对我的 user 表感到满意,并且不想在每次运行时都将其丢弃,同时继续定义其他表。

所以,我想在 user 选项上设置一个标志,sync: forced: false

module.exports = (sequelize, DataTypes) => 
  let Schema = sequelize.define(
    "user",
    
      id: 
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true
      ,
      BlaBla:
    ,
     // options
      sync: force: false,
      freezeTableName: true,
      timestamps: true
    );
  return Schema;
;

这不起作用。每次运行都会删除/创建表。

继续定义我的companytable。

module.exports = (sequelize, DataTypes) => 
  let Schema = sequelize.define(
    "company",
    
      id: 
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true
      ,
      BlaBla:
    ,
     // options
      sync: force: true,
      freezeTableName: true,
      timestamps: false
    );
  return Schema;
;

问题

如何根据sequelize.define 选项选择性地同步表?

【问题讨论】:

1.我找不到在定义中使用同步作为选项的文档。你确定这是允许的吗? 2. 如果您单独同步()表(而不是对所有表使用 sequelize.sync()),您可以在每个表上“强制”不同)。 【参考方案1】:

不支持在sequelize.define() 中选择性地同步。有关详细信息,请参阅Model Definition Configuration。在您的项目的其他地方,您必须拨打sequelize.sync(force: true) 来同步所有模型。您应该先纠正它,因为它会批量强制所有模型同步。

修复该问题后,您有几个选择:

1:继续使用迁移。对架构的每次添加或更改都会在迁移中捕获,因此您可以推出每个更改而无需重新同步其他更改。 见http://docs.sequelizejs.com/manual/migrations.html

2:按照您的建议单独同步每个表。您需要分别为每个模型调用 sync() 方法,例如:

const user = require('./user');
const company = require('./company');
company.sync();
compant.sync(force:true);

这对于早期开发可能是实用的,但随着项目的进展并开始发布,迁移应该是您推出架构更改的首选方法。

见http://docs.sequelizejs.com/manual/models-definition.html#database-synchronization

【讨论】:

【参考方案2】:

好的,经过一夜好眠,我的大脑又开始工作了。

首先。我不明白为什么所有加载模型的示例都在创建db object 保存所有模型。 db[model.name] = model 对 Sequelize 包的引用 db.Sequelize = Sequelize 对连接db.sequelize = sequelize 的引用

当实例 const sequelize = new Sequelize() 是你所需要的。

连接对象将包含对所有导入模型的引用。 public models:

给定model definition 与 OP 相同。 档案:app/models/user.js

module.exports = (sequelize, DataTypes) => 
  let Schema = sequelize.define(
    "user",
    
      id: 
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true
      ,
      BlaBla:
    ,
     // options
      sync: force: false,
      freezeTableName: true,
      timestamps: true
    );
  return Schema;
;

还有这样的引导程序: 档案:config/sequelize.js

const Sequelize = require("sequelize");

const sequelize = new Sequelize(config.dbname, config.dbuser, config.dbpass, 
    dialect: "mysql",
    host: config.dbhost,
    port:    3306,
    define: 
        engine: 'MYISAM',
        timestamps: true,
      
  );

fs
  .readdirSync(path.join(config.models))
  .filter(file => ~file.indexOf('.js'))
  .forEach((file) => 
    let model = sequelize["import"](path.join(config.models, file));
    model.sync(model.options.sync);
  );

module.exports = sequelize;

那么你就有了每个模型的同步。

然后在server.js:

const sequelize = require(join(__dirname,"config/sequelize"));
/* debug */
Object.keys(sequelize.models).forEach(function(name) 
    console.log('sequelize model:',name);
);

console.log('Checking DB connection...');
sequelize
  .authenticate()
  .then(() => 
    console.log('Successfully connected to:', config.dbname);
  )
  .catch(err => 
    console.error('Unable to connect to the database:', err);
    process.exit;
  );

const User = sequelize.model('user');

这会导致user NOT 被丢弃,但companyIS 被丢弃。

这是运行的控制台输出:

> node server.js

config/index.js  dbhost: '192.168.1.70',
  dbport: 3306,
  dbname: 'dbdev',
  dbuser: 'dbdev',
  dbpass: '********',
  mode: 'development',
  root: 'C:\\Workspace\\Github\\******',
  models: 'C:\\Workspace\\Github\\******\\app\\models',
  sync: false 

Creating DB connection...
Loading Schema: company
company sync  force: true 
Loading Schema: user
user sync  force: false 
sequelize model: company
sequelize model: user
Checking DB connection...
Server fetching: user
Executing (default): SELECT 1+1 AS result
Executing (default): DROP TABLE IF EXISTS `company`;
Executing (default): CREATE TABLE IF NOT EXISTS `user` (`id` INTEGER UNSIGNED auto_increment , `login` VARCHAR(45) UNIQUE, `password` VARCHAR(255), `fname` VARCHAR(45), `lname` VARCHAR(45), `email` VARCHAR(128), `phone` VARCHAR(20), `company` INTEGER UNSIGNED, `createdby` INTEGER UNSIGNED, `access` INTEGER, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=MYISAM;
Successfully connected to: dbdev
Executing (default): SHOW INDEX FROM `user`
Executing (default): CREATE TABLE IF NOT EXISTS `company` (`id` INTEGER auto_increment , `name` VARCHAR(255), `type` INTEGER, `createdby` INTEGER, `access` INTEGER, PRIMARY KEY (`id`)) ENGINE=MYISAM;
Executing (default): SHOW INDEX FROM `company`

我可能会看看migrations,但现在,我更愿意根据需要在定义文件中进行初始建模。

我是否遗漏了一些重要的点,或者这个解决方案是否“有效”?

【讨论】:

是的,这似乎是一种通过模型定义驱动同步的创造性和理智的方式。

以上是关于节点、Sequelize、同步模型、混合力:真/假的主要内容,如果未能解决你的问题,请参考以下文章

生信代码:机器学习-模型评价

我应该让 Sequelize 模型和迁移保持同步吗?

如何通过节点js中的sequelize更新关联记录?

Sequelize 同步与迁移

Node.js / Sequelize.js / Express.js - 如何插入多对多关联? (同步/异步?)

节点Sequelize追随者/追随者关系