Node + Sequelize:如何在添加之前检查项目是不是存在? (异步混淆)

Posted

技术标签:

【中文标题】Node + Sequelize:如何在添加之前检查项目是不是存在? (异步混淆)【英文标题】:Node + Sequelize: How to check if item exists before adding? (async confusion)Node + Sequelize:如何在添加之前检查项目是否存在? (异步混淆) 【发布时间】:2015-10-27 04:48:15 【问题描述】:

不幸的是,我是 node 新手,在 node 的异步/同步执行方面遇到了一些困惑。

我正在使用节点,使用 sqlite 和 async.js 进行续集。

我有一系列Articles,每个都有一个Authors的编号。

对于每个Article 中的每个Authors,我想检查Author 是否存在。如果没有,请创建它。

问题是,在初始运行时,正在创建重复作者,我认为由于异步功能导致检查存在问题。

例如,使用数组:authors = ['A. Test', 'B. Test', 'C. Test', 'A. Test']

和代码:

async.each(authors, function(item, callback)
    Author.sync().then(function()
      Author.count( where: name: item.trim() ).then(function(count)
        if (count != 0) 
          console.log('Author already exists')
         else 
          console.log('Creating author...')
          Author.create(
            name: item.trim()
          )
        
      )
    )
  )

在第一次运行时,将创建一个表:

ID | name
------------
0  | A. Test
1  | B. Test
2  | C. Test
3  | A. Test

我做错了什么?我似乎错过了 Node 中异步与同步执行的基本概念。

(我也尝试过 async.eachSeries 应该串行执行而不是并行执行?)

编辑:略微重构,但仍然创建重复项

async.eachSeries(authors, function(authorName, callback)
    Author.findOne( where: name: authorName.trim() ).
    then(function(author)
      if (author) 
        // Author exists...
        callback()
       else 
        // Author does not exist...
        Author.create(
          name: authorName.trim()
        ).then(function(author)
          callback()
        )
      
    )
  )

【问题讨论】:

【参考方案1】:

将你的 each 更改为 eachSeries 并实际调用回调,你应该是黄金。

async.eachSeries(authors, function(item, callback)
    Author.sync().then(function()
      Author.count( where: name: item.trim() ).then(function(count)
        if (count != 0) 
          console.log('Author already exists')
          callback(); //assuming you want it to keep looping, if not use callback(new Error("Author already exists"))
         else 
          console.log('Creating author...')
          Author.create(
            name: item.trim()
          ).then(function(author)
            callback();
          )
        
      )
    )
  )

【讨论】:

嗯,这似乎不起作用,它只是在添加第一作者。 您的 Author.create 是否支持我在 cmets 中提到的回调? 对不起,你是什么意思? create 方法是 implemented by sequelize,这会产生一个承诺 好的,可以了,谢谢!只是为了澄清我对流程的理解,调用的callback() 函数是什么?我发现async.js documentation 的措辞令人困惑。 它告诉循环继续【参考方案2】:

Author.count 并不是真正需要的,除非您需要计数。见findOrCreate()。

使用findOrCreate(),您可以拥有以下内容。 (为此编辑了trex005的sn-p)

async.eachSeries(authors, function(item, callback) 
  Author.sync().then(function() 
    Author.findOrCreate(
      where: 
        name: item.trim()
      ,
      defaults:  // set the default properties if it doesn't exist
        name: item.trim()
      
    ).then(function(result) 
      var author = result[0], // the instance of the author
        created = result[1]; // boolean stating if it was created or not

      if (!created)  // false if author already exists and was not created.
        console.log('Author already exists');
      

      console.log('Created author...');
      callback();
    );
  )
)

【讨论】:

您好,感谢您的回复,实际上我尝试了findOrCreate(并重构为添加到我上面的答案中的更简洁的 sn-p)但findOrCreate 导致了 sqlite 阻塞/的各种问题数据库锁定 - 显然这也发生在某些用户的 postgres 中。不幸的是,我的新 sn-p 仍然无法正常工作,并且仍在创建重复项。 @joshua-f 顺便说一句,您可以使用 spread 方法而不是 then 方法来分隔 promise 参数。示例:.spread(function(author, isCreated) ... ); @AliBARIN 哦,甜心,不知道。 在异步函数内部调用sync()是否有原因? @RonenTeva 不,这可能应该在异步函数之外。

以上是关于Node + Sequelize:如何在添加之前检查项目是不是存在? (异步混淆)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Sequelize 现有模型中添加列?

如何在 MySql 中使用 sequelize 运行多个原始查询?

Node.js:如何在 Sequelize 中使用 Postgres 存储过程?

Node.js - 如何使用 Sequelize 交易

如何在 Node.js 中使用 Sequelize 运行 AND 和 Or 运算符

如何在 node.js 中使用 sequelize-npm 实现与连接表的一对多关系